在用STC89C52單片機做一個溫度采集功能。
功能是這樣的:
1、工作頻率 11.0592
2、P2.0,P2.1,P2.2,P2.3 普通IO口分別接了四個S18B20溫度傳感器,用來采集溫度。
3、RX,TX分別和電腦的串口連好,實現和電腦通訊
4、電腦串口定時發送定義好的查詢幀,單片機串口收到后,判斷幀的內容,查詢溫度,并返回溫度數據。
5、功能己經實現,這樣運行的也沒有問題。
現在的操作方式是被動操作,(也就是電腦發送一幀數據,單片機查詢一次溫度,并返回)流程如下:
1,電腦串口發送定義好的16字數據 --->2、單片機串口收到數據,根據數據的類型,查詢S18B20溫度傳感器溫度---->3,單片機將溫度數據再編碼成16個字節數據發送給電腦串口---->4,電腦串口收到數據后處理并顯示
存在一個問題是:
現在我想在單片機上裝一個顯示屏,讓單片機定時不斷查詢溫度并顯示在屏幕上。
但是單片機在進行S18B20查詢溫度是很講究時序的,在1602顯示屏上顯示文字,也是講究時序的。
問題:單片機正在對S18B20查詢溫度時(IO口電平拉高,或拉底),這時有串口數據來到,會中斷當前的操作,直到中斷函數執行完畢。這時查詢S18B20的操作時序就不準確了,1602顯示屏也一樣。
問:有串口數據來到要接收,不能丟棄。對S18B20操作到一半時,也不能中斷,不然時序可能不準確。這樣怎么處理?有什么兩全其美的方法嗎?
電路圖:
2.jpg (223.91 KB, 下載次數: 24)
下載附件
2018-4-8 20:46 上傳
單片機源碼
- #include "config.h"
- #include<ds1.h>
- #include<ds2.h>
- #include<ds3.h>
- #include<ds4.h>
- void UART_init();
- void PutFrame(uchar *TXStr);
- void DataFrame_Put_init();
- void TEMP_init_var();
- uchar dataFrame[16]; //定義數據幀長度為16個字節
- uchar dataFrame_RI; //數據幀是否己讀取標記
- uchar dataFrame_temp[16]; //數據幀臨時緩沖區16個字節
- uchar dataFrame_temp_count; //定義數據幀己接收的字節數
- //定義發送數據緩沖區
- uchar DataFrame_Put[16]={DATAFRAME_HEAD,DEVICEID_1,DEVICEID_2,0,0,0,0,0,0,0,0,0,0,0,0,DATAFRAME_TAIL};
- INT32U led1_count; //運行指示燈倒計時變量
- uchar led1_count2; //運行指示燈倒計時變量2
- INT32U led2_count; //收到心跳倒計時變量
- INT32U led3_count; //有數據接收倒計時變量
- INT32U led4_count; //有數據發送倒計時變量
- #define LED1_COUNT 15000
- #define LED2_COUNT 125000
- #define LED3_COUNT 100
- #define LED4_COUNT 100
- //存儲溫度的高8位和底8位
- uchar ds_M;
- uchar ds_L;
- //溫度變量
- uchar symbol; //符號位
- uchar hundreds; //百位
- uchar decade; //十位
- uchar unit; //個位
- uchar decimal; //小數1位
- void main()
- {
- //串口初始化
- UART_init();
- while(1)
- {
- //調試使用
- //uchar dataFrame[16] = {DATAFRAME_HEAD,DEVICEID_1,DEVICEID_2,0,0,1,1,0,0,0,0,0,0,0,0,DATAFRAME_TAIL};
- //dataFrame_RI = 1; //執行時間2.17微妙
- //如果己接收到一幀數據
- if(dataFrame_RI == 1) // 執行時間5.42微秒
- {
- //收到心跳
- if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 0 && dataFrame[6] == 1){
- //收到心跳
- DataFrame_Put[3] = 0;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 0;
- DataFrame_Put[6] = 1;
- PutFrame(&DataFrame_Put);
- led2_count = LED2_COUNT;
- }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 0 && dataFrame[6] == 2){
- //收到查詢設備id
- DataFrame_Put[3] = 1;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 0;
- DataFrame_Put[6] = 2;
- DataFrame_Put[7] = DEVICEID_1;
- DataFrame_Put[8] = DEVICEID_2;
- DataFrame_Put[9] = 255;
- DataFrame_Put[10] = 255;
- DataFrame_Put[11] = 255;
- DataFrame_Put[12] = 255;
- DataFrame_Put[13] = 002;
- DataFrame_Put[14] = 001;
- PutFrame(&DataFrame_Put);
- led3_count = LED3_COUNT;
- led4_count = LED4_COUNT;
- }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 0 && dataFrame[6] == 9){
- //收到更新用戶信息時間,返回
- DataFrame_Put[3] = 1;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 0;
- DataFrame_Put[6] = 9;
- PutFrame(&DataFrame_Put);
- led3_count = LED3_COUNT;
- led4_count = LED4_COUNT;
- }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 1 && dataFrame[6] == 1){ // 執行時間15.19 微秒
- //查詢溫度1:0 0 1 1
- TEMP_init_var();
- DS1_ReadWeather(&ds_M,&ds_L);
- Convert_DS_weather(ds_M, ds_L, &symbol, &hundreds, &decade, &unit, &decimal);
- DataFrame_Put[3] = 1;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 1;
- DataFrame_Put[6] = 1;
- DataFrame_Put[7] = symbol;
- DataFrame_Put[8] = hundreds;
- DataFrame_Put[9] = decade;
- DataFrame_Put[10] = unit;
- DataFrame_Put[11] = decimal;
- PutFrame(&DataFrame_Put);
- led3_count = LED3_COUNT;
- led4_count = LED4_COUNT;
- }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 1 && dataFrame[6] == 2){
- //查詢溫度2:0 0 1 2
- TEMP_init_var();
- DS2_ReadWeather(&ds_M,&ds_L);
- Convert_DS_weather(ds_M, ds_L, &symbol, &hundreds, &decade, &unit, &decimal);
- DataFrame_Put[3] = 1;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 1;
- DataFrame_Put[6] = 2;
- DataFrame_Put[7] = symbol;
- DataFrame_Put[8] = hundreds;
- DataFrame_Put[9] = decade;
- DataFrame_Put[10] = unit;
- DataFrame_Put[11] = decimal;
- PutFrame(&DataFrame_Put);
- led3_count = LED3_COUNT;
- led4_count = LED4_COUNT;
- }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 1 && dataFrame[6] == 3){ // 執行時間15.19 微秒
- //查詢溫度3:0 0 1 3
- TEMP_init_var();
- DS3_ReadWeather(&ds_M,&ds_L);
- Convert_DS_weather(ds_M, ds_L, &symbol, &hundreds, &decade, &unit, &decimal);
- DataFrame_Put[3] = 1;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 1;
- DataFrame_Put[6] = 3;
- DataFrame_Put[7] = symbol;
- DataFrame_Put[8] = hundreds;
- DataFrame_Put[9] = decade;
- DataFrame_Put[10] = unit;
- DataFrame_Put[11] = decimal;
- PutFrame(&DataFrame_Put);
- led3_count = LED3_COUNT;
- led4_count = LED4_COUNT;
- }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 1 && dataFrame[6] == 4){
- //查詢溫度4:0 0 1 4
- TEMP_init_var();
- DS4_ReadWeather(&ds_M,&ds_L);
- Convert_DS_weather(ds_M, ds_L, &symbol, &hundreds, &decade, &unit, &decimal);
- DataFrame_Put[3] = 1;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 1;
- DataFrame_Put[6] = 4;
- DataFrame_Put[7] = symbol;
- DataFrame_Put[8] = hundreds;
- DataFrame_Put[9] = decade;
- DataFrame_Put[10] = unit;
- DataFrame_Put[11] = decimal;
- PutFrame(&DataFrame_Put);
- led3_count = LED3_COUNT;
- led4_count = LED4_COUNT;
- }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 1){
- //查詢開關1
- DataFrame_Put[3] = 1;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 2;
- DataFrame_Put[6] = 1;
- if(SW1 == 0){
- DataFrame_Put[7] = 1;
- }else{
- DataFrame_Put[7] = 2;
- }
- PutFrame(&DataFrame_Put);
- led3_count = LED3_COUNT;
- led4_count = LED4_COUNT;
- }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 2){
- //查詢開關2
- DataFrame_Put[3] = 1;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 2;
- DataFrame_Put[6] = 2;
- if(SW2 == 0){
- DataFrame_Put[7] = 1;
- }else{
- DataFrame_Put[7] = 2;
- }
- PutFrame(&DataFrame_Put);
- led3_count = LED3_COUNT;
- led4_count = LED4_COUNT;
- }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 3){
- //查詢開關3
- DataFrame_Put[3] = 1;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 2;
- DataFrame_Put[6] = 3;
- if(SW3 == 0){
- DataFrame_Put[7] = 1;
- }else{
- DataFrame_Put[7] = 2;
- }
- PutFrame(&DataFrame_Put);
- led3_count = LED3_COUNT;
- led4_count = LED4_COUNT;
- }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 4){
- //查詢開關3
- DataFrame_Put[3] = 1;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 2;
- DataFrame_Put[6] = 4;
- if(SW4 == 0){
- DataFrame_Put[7] = 1;
- }else{
- DataFrame_Put[7] = 2;
- }
- PutFrame(&DataFrame_Put);
- led3_count = LED3_COUNT;
- led4_count = LED4_COUNT;
- }else if(dataFrame[3] == 2 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 1){
- //設置開關1
- if(dataFrame[7] == 1 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
- SW1 = 0;
- }
- else if(dataFrame[7] == 2 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
- SW1 = 1;
- }
- led3_count = LED3_COUNT;
- }else if(dataFrame[3] == 2 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 2){
- //設置開關2
- if(dataFrame[7] == 1 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
- SW2 = 0;
- }
- else if(dataFrame[7] == 2 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
- SW2 = 1;
- }
- led3_count = LED3_COUNT;
- }else if(dataFrame[3] == 2 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 3){
- //設置開關3
- if(dataFrame[7] == 1 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
- SW3 = 0;
- }
- else if(dataFrame[7] == 2 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
- SW3 = 1;
- }
- led3_count = LED3_COUNT;
- }else if(dataFrame[3] == 2 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 4){
- //設置開關4
- if(dataFrame[7] == 1 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
- SW4 = 0;
- }
- else if(dataFrame[7] == 2 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
- SW4 = 1;
- }
- led3_count = LED3_COUNT;
- }
- dataFrame_RI = 0; //置數據幀己讀取
- DataFrame_Put_init(); //初始化發送幀,為下一次發送數據做準備
- }
- //LED1運行指示燈閃爍,整個循環在沒有接收數據時,執行一次約40us
- if(led1_count > 0){
- led1_count--;
- }else{
- if(led1_count2 == 0){
- led1_count2 = 1;
- }else{
- led1_count2 = 0;
- }
- led1_count = LED1_COUNT;
- }
- if(led1_count > 0){
- if(led1_count2 == 0){
- LED1 = 0;
- }else{
- LED1 = 1;
- }
- led1_count--;
- }
- //收到心跳燈亮20秒
- if(led2_count > 0){
- LED2 = 0;
- led2_count--;
- }else{
- LED2 = 1;
- }
- //有數據接收閃一下
- if(led3_count > 0){
- LED3 = 0;
- led3_count--;
- }else{
- LED3 = 1;
- }
- //有數據發送閃一下
- if(led4_count > 0){
- LED4 = 0;
- led4_count--;
- }else{
- LED4 = 1;
- }
- }
- while(1);
- }
- //初始化輸出幀
- void DataFrame_Put_init(){
- DataFrame_Put[3] = 0;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 0;
- DataFrame_Put[6] = 0;
- DataFrame_Put[7] = 0;
- DataFrame_Put[8] = 0;
- DataFrame_Put[9] = 0;
- DataFrame_Put[10] = 0;
- DataFrame_Put[11] = 0;
- DataFrame_Put[12] = 0;
- DataFrame_Put[13] = 0;
- DataFrame_Put[14] = 0;
- }
- //初始化溫度值
- void TEMP_init_var(){
- ds_M = 0;
- ds_L = 0;
- symbol = 0; //符號位
- hundreds = 0; //百位
- decade = 0; //十位
- unit = 0; //個位
- decimal = 0; //小數1位
- }
- //初始化
- void UART_init()
- {
- TMOD = 0x20; //T1工作模式2 8位自動重裝
- TH1 = 0xfd;
- TL1 = 0xfd; //比特率9600
- TR1 = 1; //啟動T1定時器
- SM0 = 0;
- SM1 = 1; //串口工作方式1 10位異步
- REN = 1; //串口允許接收
- EA = 1; //開總中斷
- ES = 1; //串口中斷打開
- }
- //串口發送一幀數據函數,一幀16個字節
- void PutFrame(uchar *TXStr)
- {
- uchar i = 0;
- while(1){
- SBUF=*TXStr;
- while(TI == 0); //對方接收后TI置1,停止等待
- TI = 0;
- i++;
- if(i > 15){break;}
- TXStr++;
- }
- }
- void UART() interrupt 4
- {
- if(RI) //檢測是否接收完成
- {
- uchar temp = SBUF;
- RI = 0;
- // 如果接收的一幀,第一個字節不是包頭標志,則拋棄這個字節
- if(dataFrame_temp_count == 0)
- {
- if(temp != DATAFRAME_HEAD)
- return;
- }
- //如果接收的一幀,最后一個字節不是包尾標志,則拋棄這幀數據
- if(dataFrame_temp_count == 15)
- {
- if(temp != DATAFRAME_TAIL){
- dataFrame_temp_count = 0;
- return;
- }
- }
- //將接收的一個字節裝入緩沖區
- dataFrame_temp[dataFrame_temp_count] = temp;
- dataFrame_temp_count++;
- //如果一幀數據接收完
- if(dataFrame_temp_count >= 16){
- //如果上一幀還沒有讀取,則拋棄這一幀
- if(dataFrame_RI == 1){
- dataFrame_temp_count = 0;
- return;
- }
- //拷貝一幀數據,并置這一幀數數沒有讀取
- dataFrame[0] = dataFrame_temp[0];
- dataFrame[1] = dataFrame_temp[1];
- dataFrame[2] = dataFrame_temp[2];
- dataFrame[3] = dataFrame_temp[3];
- dataFrame[4] = dataFrame_temp[4];
- dataFrame[5] = dataFrame_temp[5];
- dataFrame[6] = dataFrame_temp[6];
- dataFrame[7] = dataFrame_temp[7];
- dataFrame[8] = dataFrame_temp[8];
- dataFrame[9] = dataFrame_temp[9];
- dataFrame[10] = dataFrame_temp[10];
- dataFrame[11] = dataFrame_temp[11];
- dataFrame[12] = dataFrame_temp[12];
- dataFrame[13] = dataFrame_temp[13];
- dataFrame[14] = dataFrame_temp[14];
- dataFrame[15] = dataFrame_temp[15];
-
- dataFrame_temp_count = 0;
- dataFrame_RI = 1;
- }
- }
- }
復制代碼
|