本设计是由单片机控制数码管显示ph值及温度
单片机源程序如下:
- #include "N76E003.h"
- #include "SFR_Macro.h"
- #include "Function_define.h"
- #include "LED.h"
- #define BAUDRATE 9600 //通讯波特率
- void InitialUART0_Timer3(unsigned long u32Baudrate); //use timer3 as Baudrate generator
- unsigned char LedUpdateCnt=0; //LED显示更新计时
- unsigned char const num[]={ //数码管段码
- 0x3f,0x06,0x5b,0x4f,0x66,//0~4
- 0x6d,0x7d,0x07,0x7f,0x6f,//5~9
- 0x77,0x7C,0x58,0x5E,0x79,0x71,//A~F
- 0x40/*16-*/,0x3e/*17U*/,0x39/*18C*/,
- 0x76/*19H*/,0x48/*20=*/,0x00/*21灭*/
- };
- float Dispdata; //用于显示的数据
- unsigned int Time1TimesCnt; //定时器1定时溢出计数
- unsigned char ShiftDisplay=0; //切换PH、温度显示标志位
- unsigned int ShiftCnt=0; //切换显示计数器
- unsigned int RecData; //接收到的数据
- unsigned char Cache9Byte=0; //连续缓存9个字节标志位
- unsigned char EnDatadeal=0; //使能数据处理
- unsigned char receCount=0; //接收到的字节个数
- unsigned char receBuf[11]; //接收缓存区
- unsigned char i;
- void main (void)
- {
- //TIMER1用于动态扫描数码管
- TIMER1_MODE2_ENABLE;
- //未设置时钟控制寄存器CKCON中的T1M(复位值为0),时钟源为系统时钟/12,计数周期为12/16M=0.75us
- //TH1 = (256-TIMER1_CNTTIMES_VALUE);
- //TL1 = (256-TIMER1_CNTTIMES_VALUE);
- TH1 = 89; //125.25us溢出一次(计数167次后溢出中断)
- TL1 = 89;
- set_ET1; //enable Timer1 interrupt
- set_TR1; //Timer1 run
-
- InitialUART0_Timer3(BAUDRATE); //use timer3 as Baudrate generator
- set_ES; //enable UART interrupt
-
- set_EA; //enable global interrupt
-
- LED_Init();
-
- while(1)
- {
- if(EnDatadeal)
- {
- //例如:F7 10 04 01 13 00 5C 9E 9F (有效数据是第4、5、6、7字节)
-
- if(ShiftDisplay) RecData= (receBuf[3]<<8)| receBuf[4]; //转换第4、5字节数据(温度)
- else RecData= (receBuf[5]<<8)| receBuf[6]; //转换第6、7字节数据(PH值)
-
- for(i=0;i<receCount;i++)receBuf[i]=0; //清接收缓存
- receCount = 0; //清接收数
- EnDatadeal=0; //数据处理完成
- REN=1; //允许新一轮接收
- }
- }
- }
- //定时器1溢出中断:125.25us溢出一次
- void Timer1_ISR (void) interrupt 3
- {
- if(Time1TimesCnt>=16) //计数1次时间为0.12525ms,16次为2.004ms
- {
- Time1TimesCnt=1;
-
- if(Dispdata>=10.0)
- {
- switch(LedUpdateCnt%7)//每隔4ms扫描一个数码管,每轮扫描时长16ms<40ms(理论上人眼的视觉延迟感应速度为>=40ms)
- {
- case 0: LED_Light(num[(int)(Dispdata/10.0)],1);break;
- case 2: LED_Light(num[((int)Dispdata)%10]+0x80,2); break;
- case 4: LED_Light(num[((int)(Dispdata*10.0))%10],3); break;
- case 6: //LED_Light(num[21],4);break;
- default : break;
- }
- }
- else
- {
- switch(LedUpdateCnt%7)//每隔4ms扫描一个数码管,每轮扫描时长16ms<40ms(理论上人眼的视觉延迟感应速度为>=40ms)
- {
- case 0: LED_Light(num[((int)Dispdata)%10]+0x80,1); break;
- case 2: LED_Light(num[((int)(Dispdata*10.0))%10],2); break;
- case 4: LED_Light(num[((int)(Dispdata*100.0))%10],3); break;
- case 6: //LED_Light(num[21],4);break;
- default : break;
- }
-
- }
-
- //112除以7=16
- if(LedUpdateCnt<112) LedUpdateCnt++;
- else //2.004ms*112=224.448ms更新一次显示数据,扫16轮后切换一个新数据扫描
- {
- LedUpdateCnt=0;
- Dispdata=RecData/10.0;
- }
-
- if(ShiftCnt<5000) ShiftCnt++;
- else//5000*2ms=10S
- {
- if(ShiftDisplay) ShiftDisplay=0;
- else ShiftDisplay=1;
- ShiftCnt=0;
- }
- }
- else Time1TimesCnt++;
- // 清除更新中断标记,防止不断进入中断程序
- clr_TF1;
- }
- //串口0中断
- void SerialPort_ISR(void) interrupt 4
- {
- unsigned char i,Recev=0; //定义变量,用来转存接收数据
-
- if (RI) /* if reception occur */
- {
- clr_RI; /* clear reception flag for next reception */
- Recev = SBUF; //收到的数值放在变量(暂存)中
- //接收到f7且之前未接收数据则缓存9个字节(一帧完整数据共9个字节)
- //例如:F7 10 04 01 13 00 5C 9E 9F (间隔500ms发送一次数据的前3个字节是固定的)
- if(Recev==247 && receCount==0) Cache9Byte=1;//使能缓存9个字节
-
- if(Cache9Byte)
- {
- receBuf[receCount] = Recev; //缓存
- receCount++; //接收计数加1
-
- if(receCount==9)
- {
- if(receBuf[1]==16 && receBuf[2]==4) //前3字节分别是:F7 10 04
- {
- REN=0;//禁止接收
- Cache9Byte=0; //缓存标志清理
- EnDatadeal=1; //使能数据处理
-
- //下面指令在程序处理完当前接收到的数据之后再执行
- //也就是下一轮接收仅再本轮接收完成的数据处理好后才允许再次进行
- //for(i=0;i<receCount;i++)receBuf[i]=0; //清接收缓存
- //receCount = 0; //清接收数
- //EnDatadeal=0; //数据处理完成
- //REN=1; //允许新一轮接收
- }
- else
- {
- //未能正常接收,清理已接收的缓存区,清理后重新来过,清理过程中禁止新的接收
- REN=0;//禁止接收
- for(i=0;i<receCount;i++)receBuf[i]=0; //清接收缓存
- Cache9Byte=0; //缓存标志清理
- receCount = 0; //清接收计数器
- REN=1; //允许新一轮接收
- }
- }
- }
- }
- if(TI) //接收中断过程中禁止发送
- {
- clr_TI; /* if emission occur */
- }
- }
- void InitialUART0_Timer3(unsigned long u32Baudrate) //use timer3 as Baudrate generator
- {
- P06_Quasi_Mode; //Setting UART pin as Quasi mode for transmit
- P07_Quasi_Mode; //Setting UART pin as Quasi mode for transmit
-
- SCON = 0x50; //UART0 Mode1,REN=1,TI=1
- set_SMOD; //UART0 Double Rate Enable
- T3CON &= 0xF8; //T3PS2=0,T3PS1=0,T3PS0=0(Prescale=1)
- set_BRCK; //UART0 baud rate clock source = Timer3
-
- RH3 = ( (unsigned char)( (65536 - (1000000/u32Baudrate)-1) >>8 ) ); /*16 MHz */
- RL3 = ( (unsigned char)( (65536 - (1000000/u32Baudrate)-1) &0xff) ); /*16 MHz */
-
- set_TR3; //Trigger Timer3
- set_TI; //For printf function must setting TI = 1
- }
复制代码
所有资料51hei提供下载:
PH串口模块 1米PH温度电极 试剂采集器温度传感器酸碱度水质检测.rar
(105.39 KB, 下载次数: 61)
|