碎碎念:好久没写串口,来个串口熟悉熟悉,结果发现好多问题
一.题目要求:
个人的一些见解:这一届两个比较少见的点就是串口通信收发不定长数据和按键长按短按的识别
具体可以看这两篇文章 蓝桥杯学习笔记 单片机CT107D 按键短按,长按的识别_兰倩单片机长按短按怎么写-CSDN博客
蓝桥杯学习笔记 单片机CT107D 串口通信_ct107d平台外设程序学习心得-CSDN博客
先说串口吧,对于不定长数据的发送可利用指针指向字符串数组中的值挨个发送直到最后('\0')
void UART_Service() interrupt 4
{
if(RI==1)
{
RI=0;
Receive[len++]=SBUF;
}
}
对于之后字符串的处理,我采用了比较投机取巧的方法,就是字符串中元素一个一个判断,判断完成后将数组清零
void UART_deal()
{
unsigned char i;
if(Receive[0]=='S'&&Receive[1]=='T')
{
UART_SendByte('$');
UART_SendByte(Distance/10+48);
UART_SendByte(Distance%10+48);
UART_SendByte(',');
UART_SendByte(T_smg/1000+48);
UART_SendByte(T_smg%1000/100+48);
UART_SendByte('.');
UART_SendByte(T_smg%100/10+48);
UART_SendByte(T_smg%10+48);
SendString("\r\n");
}
else if(Receive[0]=='P'&&Receive[1]=='A'&&Receive[2]=='R'&&Receive[3]=='A')
{
UART_SendByte('#');
UART_SendByte(Dis_param/10+48);
UART_SendByte(Dis_param%10+48);
UART_SendByte(',');
UART_SendByte(T_param/10+48);
UART_SendByte(T_param/10+48);
SendString("\r\n");
}
else if(Receive[0]!=0)
{
SendString("error\r\n");
}
len=0;
for(i=0;i<4;i++)
{
Receive[i]=0;
}
}
其实上述代码的数据发送也用了比较取巧的方法,就是将一个字符串分成几段挨个发出去,当然也可以用spritnf将字符串拼接后发送。但我使用的时候使用unsigned char 类型会出问题,不得己全部换成了 int类型
int Distance
sprintf(string,"$%d,%.2f\r\n",Distance,T);
SendString(string);
按键长短按问题的识别我采用的策略是按下按键后立即进入while循环并开始按键相关的计时,松开按键后关闭计时,之后判断时间执行相应的操作:
中断函数的配置
void Timer0_Service() interrupt 1
{
times++;
if(times==125)
{
Measure_Distance();
}
if(Key_Flag==1) //打开按键定时标志位
{
Key_times++;
}
}
按键中的配置(设计长按的两个部分)
void Scan_Key()
{
C1=0;C2=1;
R1=R2=1;
if(R1==0)
{
Delay_SMG(500);
if(R1==0)
{
Key_Flag=1; //打开定时标志位
while(R1==0)
{
Display_Dynamic();
DS18B20_Read();
}
Key_Flag=0; //关闭定时标志位
if(Key_times<1000) //开始计时
{
if(SMG_Mode!=4&&SMG_Mode!=5)
{
SMG_Mode=4;
}
else if(SMG_Mode==4||SMG_Mode==5)
{
SMG_Mode=1;
AT24C02_Write(++change_times);
}
}
if(Key_times>1000)
{
DAC_Flag=~DAC_Flag;
}
Key_times=0;
}
while(R1==0)
{
Display_Dynamic();
DS18B20_Read();
}
}
if(R2==0)
{
Delay_SMG(500);
if(R2==0)
{
Key_Flag=1;
while(R2==0)
{
Display_Dynamic();
DS18B20_Read();
}
Key_Flag=0;
if(Key_times<1000)
{
if(SMG_Mode!=4&&SMG_Mode!=5)
{
switch(SMG_Mode)
{
case 1:
SMG_Mode=2;
break;
case 2:
SMG_Mode=3;
break;
case 3:
SMG_Mode=1;
break;
}
}
else if(SMG_Mode==4||SMG_Mode==5)
{
switch(SMG_Mode)
{
case 4:
SMG_Mode=5;
break;
case 5:
SMG_Mode=4;
break;
}
}
}
if(Key_times>=1000)
{
change_times=0;
AT24C02_Write(change_times);
}
Key_times=0;
}
}
}
二.代码实现
main.c
#include <STC15F2K60S2.H>
#include "stdio.h"
#include "intrins.h"
#include "onewire.h"
#include "iic.h"
sbit C1=P3^5;
sbit C2=P3^4;
sbit R1=P3^2;
sbit R2=P3^3;
sbit TX=P1^0;
code unsigned char SMG_Nodot[] =
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
code unsigned char SMG_Dot[] =
{0x40,0x79,0x24,0x30,0x19,0x12,0x12,0x78,0x00,0x10};
unsigned char SMG_Mode=1;
float T;
unsigned int T_smg;
int Distance;
unsigned int change_times;
unsigned char T_param=30;
unsigned char Dis_param=35;
unsigned char times;
unsigned int PCA_times;
unsigned char PCA_Flag;
unsigned char jiaoyan;
unsigned int Key_times=0;
bit Key_Flag;
unsigned char len;
unsigned char Receive[5];
unsigned char string[20];
bit DAC_Flag=1;
unsigned char DAC_Value;
unsigned char LED_Mode=0xff;
void Delay_SMG(unsigned int t)
{
while(t--);
}
void Delay12us() //@12.000MHz
{
unsigned char i;
_nop_();
_nop_();
i = 33;
while (--i);
}
void SendWave()
{
unsigned char i;
for(i=0;i<8;i++)
{
TX=1;
Delay12us();
TX=0;
Delay12us();
}
}
void SelectHC573(unsigned char channel,unsigned char dat)
{
P0=dat;
switch(channel)
{
case 4:
P2=(P2&0x1f)|0x80;
break;
case 5:
P2=(P2&0x1f)|0xa0;
break;
case 6:
P2=(P2&0x1f)|0xc0;
break;
case 7:
P2=(P2&0x1f)|0xe0;
break;
case 0:
P2=(P2&0x1f)|0x00;
break;
}
P2=(P2&0x1f)|0x00;
}
void SMG_Display(unsigned char pos ,unsigned char dat)
{
SelectHC573(6,0x01<<(pos-1));
SelectHC573(7,dat);
Delay_SMG(500);
SelectHC573(6,0x01<<(pos-1));
SelectHC573(7,0xff);
}
void Display_Dynamic()
{
if(SMG_Mode==1)
{
SMG_Display(1,SMG_Nodot[15]);
SMG_Display(5,SMG_Nodot[T_smg/1000]);
SMG_Display(6,SMG_Dot[T_smg%1000/100]);
SMG_Display(7,SMG_Nodot[T_smg%100/10]);
SMG_Display(8,SMG_Nodot[T_smg%10]);
}
if(SMG_Mode==2)
{
SMG_Display(1,0xc7);
SMG_Display(7,SMG_Nodot[Distance/10]);
SMG_Display(8,SMG_Nodot[Distance%10]);
}
if(SMG_Mode==3)
{
SMG_Display(1,SMG_Dot[0]);
if(change_times>10000)
{
SMG_Display(4,SMG_Nodot[change_times/10000]);
}
if(change_times>1000)
{
SMG_Display(5,SMG_Nodot[change_times%10000/1000]);
}
if(change_times>100)
{
SMG_Display(6,SMG_Nodot[change_times%1000/100]);
}
if(change_times>10)
{
SMG_Display(7,SMG_Nodot[change_times%100/10]);
}
SMG_Display(8,SMG_Nodot[change_times%10]);
}
if(SMG_Mode==4)
{
SMG_Display(1,0x92);
SMG_Display(4,SMG_Nodot[1]);
SMG_Display(7,SMG_Nodot[T_param/10]);
SMG_Display(8,SMG_Nodot[T_param%10]);
}
if(SMG_Mode==5)
{
SMG_Display(1,0x92);
SMG_Display(4,SMG_Nodot[2]);
SMG_Display(7,SMG_Nodot[Dis_param/10]);
SMG_Display(8,SMG_Nodot[Dis_param%10]);
}
}
void Measure_Distance()
{
CH=CL=0;
SendWave();
CR=1;
if(PCA_Flag==0)
{
Distance=99;
}
if(PCA_Flag==1)
{
Distance=PCA_times*0.017;
if(Distance>=99)
{
Distance=99;
}
}
}
void Timer0Init(void) //1??@12.000MHz
{
AUXR &= 0x7F; //?????12T??
TMOD &= 0xF0; //???????
TL0 = 0x18; //??????
TH0 = 0xFC; //??????
TF0 = 0; //??TF0??
TR0 = 1; //???0????
ET0=1;
EA=1;
}
void UartInit(void) //9600bps@12.000MHz
{
SCON = 0x50; //8???,?????
AUXR &= 0xBF; //???1???Fosc/12,?12T
AUXR &= 0xFE; //??1?????1???????
TMOD &= 0x0F; //?????1?16???????
TL1 = 0xE6; //??????
TH1 = 0xFF; //??????
ET1 = 0; //?????1??
TR1 = 1; //?????1
ES=1;
}
void PCA_Init()
{
CMOD=0x01;
CCON=0x00;
CCAPM0=0x11;
}
void Timer0_Service() interrupt 1
{
times++;
if(times==125)
{
Measure_Distance();
}
if(Key_Flag==1)
{
Key_times++;
}
}
void PCA_Service() interrupt 7
{
CR=0;
if(CF==1)
{
CF=0;
PCA_Flag=0;
}
if(CCF0==1)
{
CCF0=0;
PCA_times=CCAP0H<<8|CCAP0L;
PCA_Flag=1;
}
}
void UART_SendByte(unsigned char dat)
{
SBUF=dat;
while(TI==0);
TI=0;
}
void SendString(unsigned char *str)
{
while(*str!='\0')
{
UART_SendByte(*str++);
}
}
void UART_Service() interrupt 4
{
if(RI==1)
{
RI=0;
Receive[len++]=SBUF;
}
}
void UART_deal()
{
unsigned char i;
if(Receive[0]=='S'&&Receive[1]=='T')
{
UART_SendByte('$');
UART_SendByte(Distance/10+48);
UART_SendByte(Distance%10+48);
UART_SendByte(',');
UART_SendByte(T_smg/1000+48);
UART_SendByte(T_smg%1000/100+48);
UART_SendByte('.');
UART_SendByte(T_smg%100/10+48);
UART_SendByte(T_smg%10+48);
SendString("\r\n");
}
else if(Receive[0]=='P'&&Receive[1]=='A'&&Receive[2]=='R'&&Receive[3]=='A')
{
UART_SendByte('#');
UART_SendByte(Dis_param/10+48);
UART_SendByte(Dis_param%10+48);
UART_SendByte(',');
UART_SendByte(T_param/10+48);
UART_SendByte(T_param/10+48);
SendString("\r\n");
}
else if(Receive[0]!=0)
{
SendString("error\r\n");
}
len=0;
for(i=0;i<4;i++)
{
Receive[i]=0;
}
}
void DS18B20_Read()
{
unsigned char MSB,LSB;
unsigned int temp;
init_ds18b20();
Display_Dynamic();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Display_Dynamic();
init_ds18b20();
Display_Dynamic();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB=Read_DS18B20();
MSB=Read_DS18B20();
Display_Dynamic();
temp=MSB<<8|LSB;
T=temp*0.0625;
T_smg=T*100;
}
void AT24C02_Write(unsigned int dat)
{
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(0x00);
I2CWaitAck();
I2CSendByte(dat>>8);
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CSendByte(0xff);
I2CWaitAck();
I2CStop();
}
void AT24C02_Read(unsigned char address)
{
unsigned char MSB,LSB;
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(address);
I2CWaitAck();
if(address==0x00)
{
I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();
MSB=I2CReceiveByte();
I2CSendAck(0);
LSB=I2CReceiveByte();
I2CSendAck(1);
I2CStop();
change_times=MSB<<8|LSB;
}
if(address==0x02)
{
I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();
jiaoyan=I2CReceiveByte();
I2CSendAck(1);
I2CStop();
}
}
void DAC_Caculate()
{
if(Distance<Dis_param)
{
DAC_Value=102;
}
if(Distance>Dis_param)
{
DAC_Value=204;
}
if(DAC_Flag==0)
{
DAC_Value=51*0.4;
}
}
void DAC_Write()
{
DAC_Caculate();
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x43);
I2CWaitAck();
I2CSendByte(DAC_Value);
I2CWaitAck();
I2CStop();
}
void Scan_Key()
{
C1=0;C2=1;
R1=R2=1;
if(R1==0)
{
Delay_SMG(500);
if(R1==0)
{
Key_Flag=1;
while(R1==0)
{
Display_Dynamic();
DS18B20_Read();
}
Key_Flag=0;
if(Key_times<1000)
{
if(SMG_Mode!=4&&SMG_Mode!=5)
{
SMG_Mode=4;
}
else if(SMG_Mode==4||SMG_Mode==5)
{
SMG_Mode=1;
AT24C02_Write(++change_times);
}
}
if(Key_times>1000)
{
DAC_Flag=~DAC_Flag;
}
Key_times=0;
}
while(R1==0)
{
Display_Dynamic();
DS18B20_Read();
}
}
if(R2==0)
{
Delay_SMG(500);
if(R2==0)
{
Key_Flag=1;
while(R2==0)
{
Display_Dynamic();
DS18B20_Read();
}
Key_Flag=0;
if(Key_times<1000)
{
if(SMG_Mode!=4&&SMG_Mode!=5)
{
switch(SMG_Mode)
{
case 1:
SMG_Mode=2;
break;
case 2:
SMG_Mode=3;
break;
case 3:
SMG_Mode=1;
break;
}
}
else if(SMG_Mode==4||SMG_Mode==5)
{
switch(SMG_Mode)
{
case 4:
SMG_Mode=5;
break;
case 5:
SMG_Mode=4;
break;
}
}
}
if(Key_times>=1000)
{
change_times=0;
AT24C02_Write(change_times);
}
Key_times=0;
}
}
C1=1;C2=0;
R1=R2=1;
if(R1==0)
{
Delay_SMG(500);
if(R1==0)
{
if(SMG_Mode==4)
{
T_param+=2;
if(T_param>99)
{
T_param=99;
}
}
if(SMG_Mode==5)
{
Dis_param+=5;
if(Dis_param>99)
{
Dis_param=99;
}
}
}
while(R1==0)
{
Display_Dynamic();
DS18B20_Read();
}
}
if(R2==0)
{
Delay_SMG(500);
if(R2==0)
{
if(SMG_Mode==4)
{
if(T_param>0)
{
T_param-=2;
}
}
if(SMG_Mode==5)
{
if(Dis_param>0)
{
Dis_param-=5;
}
}
}
while(R2==0)
{
Display_Dynamic();
DS18B20_Read();
}
}
}
void Sys_Init()
{
SelectHC573(4,0xff);
SelectHC573(5,0x00);
Timer0Init();
PCA_Init();
UartInit();
AT24C02_Read(0x02);
if(jiaoyan==0xff)
{
AT24C02_Read(0x00);
}
if(jiaoyan!=0xff)
{
AT24C02_Write(0);
}
}
void LED_Control()
{
if(T>T_param)
{
LED_Mode&=0xfe;
SelectHC573(4,LED_Mode);
}
if(T<T_param)
{
LED_Mode|=0x01;
SelectHC573(4,LED_Mode);
}
if(Distance>Dis_param)
{
LED_Mode&=0xfd;
SelectHC573(4,LED_Mode);
}
if(Distance<Dis_param)
{
LED_Mode|=0x02;
SelectHC573(4,LED_Mode);
}
if(DAC_Flag==1)
{
LED_Mode&=0xfb;
SelectHC573(4,LED_Mode);
}
if(DAC_Flag==0)
{
LED_Mode|=0x04;
SelectHC573(4,LED_Mode);
}
}
void main()
{
Sys_Init();
while(1)
{
Display_Dynamic();
DS18B20_Read();
Scan_Key();
UART_deal();
DAC_Write();
LED_Control();
}
}