做题思路
首先写上要做的模块,界面,晓得细节 一页纸就能让你不用看pdf即可写出整套题这种 简单示范:
首先smg
void smg()
{
P2 = (P2&0x1f)|0xc0; P0 = T_COM[smg_i]; P2 = (P2&0x1f);
P2 = (P2&0x1f)|0xe0; P0 = ~table[smg_i]; P2 = (P2&0x1f);
smg_i++;
smg_i &= 0x07;
}
长短矩阵按键
我的思路:
- 首先先把状态机一次按键写出(用于去抖动)
- 在一次按键的基础上,检测按键按下(无抖动的一次按键下) 到松开,所花的时间是否大于950ms
- 最后赋值(是否*10)来区别长短按键
bit flag_changan;
void tm1_isr() interrupt 3 using 1
{
if (count-- == 0)
{
count = 1000;
}
if(flag_changan) {key_count++;} else key_count = 0;
}
u8 key_scan()
{
u8 key_return = 99, key = 99;
h1 = 1; h2 = 1; h3 = 1; h4 = 1;
l1 = 1; l2 = 1; l3 = 0; l4 = 1;
if(h3 != 1) key = 13;
if(h4 != 1) key = 12;
h1 = 1; h2 = 1; h3 = 1; h4 = 1;
l1 = 1; l2 = 1; l3 = 1; l4 = 1;
if(h3 != 1) key = 17;
if(h4 != 1) key = 16;
switch(key_state)
{
case 0: if(key != 99) key_state = 1; flag_changan = 0; break;
case 1: if(key == 99) key_state = 0;
else{key_val = key; key_state = 2; flag_changan = 1; } break;
case 2: if(key == 99) { if(key_count>980) key_return = key_val*10;
else key_return = key_val;
key_state = 0; flag_changan = 0; }
break;
return key_return;
}
串口收发问题
一般我们使用串口1和串口2,而用于串口1的定时器可以是T0,也可以是T2 但要注意,串口1的中断使能为EA = 1; 而串口2的中断使能为IE2 = 1; 然后在使用isp自动生成波特率代码时要注意咯,在本题中由于定时器0超声波计时(12分频),定时器1用于1ms中断,控制所用程序的一个计时,故我们串口就用定时器2,记得区分串口中断!(记得勾选上)
首先附上标准代码
void Uart_Isr() interrupt 4 using 1
{
u8 a,i;
if (RI)
{
RI = 0;
a = SBUF;
receive[rcv] = a;
rcv++;
}
if (TI)
{
TI = 0;
busy = 0;
}
}
串口重定向:用printf(""); 来发送字符串 printf("%d",t); 可以发送变量 记得加头文件#include<stdio.h>
char putchar(char c)
{
ES=0;
SBUF=c;
while(TI!=1);
TI=0;
ES=1;
return c;
}
在上位机发送命令小例子 字符 ‘’ 字符串 “” 注意下述代码放在while函数里哟,不能放在中断~~~原因在最底部
if(rcv>2&& receive[rcv-2] == '\r' && receive[rcv-1] == '\n')
{
rcv = 0;
for (i = 0;i <8;i++)
{
receive[i] = '\0';
}
}
if(receive[0] == 'S' && receive[1] == 'T') {printf("the Temp is %d ℃\n\t",t);}
DS18B20
特别好写,for延时12次。 最后也只用写这么点代码就可以读温度啦 首先定义变量 然后初始化 然后skip rom 然后转换温度 转换温度记得要延时一会(若还是读不出来就要关中断啦) 然后我们要读温度啦,继续初始化 然后skip rom 然后先读低再度高 将所读的加起来16位数据右移4位(*0.0625)就是真实温度,但考虑到小数不方便,直接我们放大100倍得u16 最后记得要返回温度哟
u16 r_t()
{
u8 l,h;
u16 temp;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Delay_OneWire(20);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
l = Read_DS18B20();
h = Read_DS18B20();
temp = ((u16)h<<8|l)*6.25;
return temp;
}
超声波
记得跳线帽要插好,不然就是一直99(害) 超声波的思路就是通过发送8个脉冲 {TX = 1;延时 TX = 0; 延时}(8个) 发送8个是为了超声波能够接受回数据 然后打开定时器0(初始化定时器0时记得清空TL0,TH0 以及 12分频) while(TF0 != 1 && RX != 0 ); //注意这个为&&,两个同时满足才会一直等待 while语句来记录接收到信号的时间,如果没有接收到就会溢出,我们直接写distance = 99 即可。 同时记得数据初始化,方便下一次的定时计数。
void sendsonic()
{
u8 i;
for(i=0;i<8;i++)
{
TX = 1;
somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
TX = 0;
somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
}
}
void r_distance()
{
sendsonic();
TR0 = 1;
while(TF0 != 1 && RX != 0 );
TR0 = 0;
if(RX == 0)
{
distance = (TH0*256+TL0)*0.017;
TL0 = 0;
TH0 = 0;
}
else
{distance = 99;
TF0 = 0;
TL0 = 0;
TH0 = 0;
}
}
AT24c02
这个也是照着新派呢手册打代码,记得DAC输出电压通道是0x40 并且读取eeprom的数据前要延时5ms,不然会有问题,只需要在前面加就行啦
Delay5ms() ;
index_change = at24_r(0x55);
at24_w(0x55,++index_change);
void at24_w(u8 add,u8 dat)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
u8 at24_r(u8 add)
{
u8 temp;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
temp = IIC_RecByte();
IIC_Stop();
return temp;
}
最后串口的问题
在代码1中,你想在串口中断里发送一堆数据?? 串口中断似乎一次智能处理一个字符,而你想用printf发字符串,显然寄了 所以还是安心放在while函数里吧!
|