先说写的时候遇到问题,看看笑笑就好:
//按键扫描不熟练 时间长忘记了
//超声波测距刚开始出现小问题 判断接收成功条件是 while(TF1==0 && RX==1); 不能写成TF1=1;写的多了写的时候就不思考了哈哈哈,
//发送一个字节函数参数定义是void sendbyte(unsigned char byte)
//发送字符串函数的参数定义为char void sendstring(char str[])
//sprintf 函数的用法
// while(TI==0); TI=0;
//* WARNING L15: MULTIPLE CALL TO SEGMENT这个问题!
//例如在主循环里调用了一个函数,而在中断服务中,你又一次调用了同样的函数。这样当主循环运行到该函数中时, 一旦产生中断,
//则在中断里又再次调用该函数!而使得该子函数发生了重入,这时,经管概率很低,但是很可能出错! reentrant重入函数关键字
//改来改去把data整爆了 回不去了 正常data105个,现在100个都不行 其实是头文件错综复杂的包含错误。写51程序的时候就正常写就行,分太多变量几个文件都要用,头文件包含错误的话不好找错误,找了好久。第二遍的代码就不展示了,代码还是第一遍的完美代码
//函数加了串口的一些功能 电脑给单片机发送指令 单片机执行并且把命令回显到串口助手
//#include "stdio.h"
// sprintf(arry,"Distance:%dcm",distance);
// sendstring(arry);
//led函数没写 太简单
题目如下:
//加了串口的一些功能 电脑给单片机发送指令 单片机执行并且把命令回显到串口助手
//#include "stdio.h"
// sprintf(arry,"Distance:%dcm",distance);
// sendstring(arry);
//led函数没写 太简单
#include "stc15f2k60s2.h"
#include "intrins.h"
#include "stdio.h"
#define somenop Delay12us()
sbit TX=P1^0;
sbit RX=P1^1;
unsigned char code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xc1};
unsigned char dscom=0;
unsigned char dsbuff[8]={10,10,10,10,10,10,10,10};
unsigned char lednum=0xf0;
unsigned char keysta[2][4]={{1,1,1,1},{1,1,1,1}};
unsigned char keybackup[2][4]={{1,1,1,1},{1,1,1,1}};
unsigned char keybuff[2][4]={{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff}};
unsigned char code keycode[2][4]={{5,9,13,17},
{4,8,12,16}};
sbit l0=P4^4;
sbit l1=P4^2;
sbit l2=P3^5;
sbit l3=P3^4;
sbit h2=P3^2;
sbit h3=P3^3;
unsigned char ym_mode=1; // 1-距离界面 2-参数界面
unsigned int distance_parameter=30; // 距离参数
unsigned int distance=123; //测量的距离
bit csb_bit=0;
char arry[18];
void keyaction(unsigned char keydat);
void keysong(unsigned char keydat);
void yemian();
void Delay12us() //@12.000MHz
{
unsigned char i;
_nop_();
_nop_();
i = 33;
while (--i);
}
void select573(unsigned char channel)
{
P2&=0x1f;
P0=0xff;
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;
}
}
void allinit()
{
select573(4);P0=0xff;
select573(5);P0=0x00;
select573(6);P0=0xff;
select573(7);P0=0xff;
}
void display()
{
select573(7);
P0=0xff;
select573(6);
P0=(1<<dscom);
select573(7);
P0=tab[dsbuff[dscom]];
P2&=0x1f;
if(++dscom==8)
dscom=0;
}
void UartInit(void) //9600bps@12.000MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x01; //串口1选择定时器2为波特率发生器
AUXR &= 0xFB; //定时器2时钟为Fosc/12,即12T
T2L = 0xE6; //设定定时初值
T2H = 0xFF; //设定定时初值
AUXR |= 0x10; //启动定时器2
ES=1;
}
void timer0init()
{
TMOD=TMOD&0xf0;
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
TF0=0;
TR0=1;
ET0=1;
EA=1;
TH1=0;
TL1=0;
}
void sendwave()
{
unsigned char i=0;
for(i=0;i<8;i++)
{
TX=1;
somenop;
TX=0;
somenop;
}
}
//超声波测量距离
unsigned int ultrasonic_ranging()
{
unsigned int distan;
TMOD=TMOD&0x0f;
ET1=0;
TF1=0;
TH1=0;
TL1=0;
sendwave();
TR1=1;
while((RX==1)&&(TF1==0));
TR1=0;
if(TF1==1)
{
distan=888;
}
else
distan=(TH1*256+TL1)*0.017;
if(distan>450)
{
distan=999;
}
return distan;
}
//=============发送字节======================
void sendbyte(unsigned char byte)
{
SBUF=byte;
while(TI==0);
TI=0;
}
//============发送字符串========================
void sendstring(char str[])
{
unsigned char i=0;
while(str[i]!='\0')
{
sendbyte(str[i]);
i++;
}
}
//================按键函数==============================================================================================================
//========按键扫描
void keyscan()
{
unsigned char i;
static unsigned char j=0;
keybuff[j][0]=keybuff[j][0]<<1|l0;
keybuff[j][1]=keybuff[j][1]<<1|l1;
keybuff[j][2]=keybuff[j][2]<<1|l2;
keybuff[j][3]=keybuff[j][3]<<1|l3;
for(i=0;i<4;i++)
{
if((keybuff[j][i]&0x0f)==0)
{
keysta[j][i]=0;
}
else if((keybuff[j][i]&0x0f)==0x0f)
{
keysta[j][i]=1;
}
}
j++;
if(j>=2)
j=0;
switch(j)
{
case 0:h2=0;h3=1;break;
case 1:h3=0;h2=1;break;
}
}
//========按键处理
void keyhandle()
{
unsigned char i,j;
for(i=0;i<2;i++)
{
for(j=0;j<4;j++)
{
if(keybackup[i][j]!=keysta[i][j])
{
if(keysta[i][j]==0)
{
keyaction(keycode[i][j]);
// number++;
}
else if(keysta[i][j]==1)
{
keysong(keycode[i][j]);
}
keybackup[i][j]=keysta[i][j];
}
}
}
}
//========按键按下
void keyaction(unsigned char keydat)
{
if(keydat==4)
{
if(ym_mode==1)
ym_mode=2;//参数界面
else if(ym_mode==2)
ym_mode=1;//距离界面
}
else if(keydat==8)//在距离界面按下 把当前距离设置为距离参数
{
if(ym_mode==1)
{
distance_parameter=distance;
}
}
else if(keydat==12)//在“参数显示界面”时,按下S12,当前距离参数加10cm。
{
if(ym_mode==2)
{
distance_parameter+=10;
}
}
else if(keydat==16)//在“参数显示界面”时,按下S16,当前距离参数减10cm。
{
if(ym_mode==2)
{
distance_parameter-=10;
if(distance_parameter==0)
distance_parameter=0;
}
}
else if(keydat==9)//“发送”按键,每次按下,串口将当前检测的距离数据发送给PC端的串口
{
sprintf(arry,"Distance:%dcm\r\n",distance);
sendstring(arry);
}
}
//========按键松开
void keysong(unsigned char keydat)
{
if(keydat==4)
{
}
}
//======================================================================================================================
void main()
{
allinit();
timer0init();
UartInit();
while(1)
{
keyhandle();
if(csb_bit==1)
{
csb_bit=0;
distance=ultrasonic_ranging();
}
}
}
//=======================中断函数============================================================================================================
unsigned char csb_count=0;
void timer0()interrupt 1
{
keyscan();
display();
yemian();
csb_count++;
if(csb_count>=200)
{
csb_count=0;
csb_bit=1;
}
}
void yemian()
{
if(ym_mode==1)
{
dsbuff[0]=11;
dsbuff[1]=1;
dsbuff[2]=10;
dsbuff[3]=10;
dsbuff[4]=10;
dsbuff[5]=distance/100;
dsbuff[6]=distance/10%10;
dsbuff[7]=distance%10;
}
else if(ym_mode==2)
{
dsbuff[0]=11;
dsbuff[1]=2;
dsbuff[2]=10;
dsbuff[3]=10;
dsbuff[4]=10;
dsbuff[5]=distance_parameter/100;
dsbuff[6]=distance_parameter/10%10;
dsbuff[7]=distance_parameter%10;
}
}
void usart()interrupt 4
{
static unsigned char i=0;
if(RI==1)
{
RI=0;
arry[i]=SBUF;
if(arry[i]=='\n'&&arry[i-1]=='\r')
{
i=0;
sendstring(arry);
select573(4);
lednum=~lednum;
P0=lednum;
}
else
i++;
}
}