/************STC12C5A60S2单片机 矩阵按键单次触发实验uart***************
程序功能:上位机配套的矩阵键盘下位机代码
开发环境:Keil4
硬件环境:CEPARK多功能开发学习板/实验箱(2017版),STC12C5A60S2,11.0592M晶振
接线说明:单片机P0口接底板JP29,具体接线为:P00-L1,P01-L2,P02-L3,P03-L4,P04-L5,P05-L6,P06-L7,P07-L8
跳线说明:无
实验现象: 打开上位机软件,打开相应串口,注意串口号要选对,注意晶振为11.0592M
点击打开矩阵按键界面 ,当按下底板矩阵键盘上的一个按键时,上位机对应的按钮动作显示被按下并记录按下的次数。
上位机相关:
//uart0采用独立波特率发生器,独立波特率发生器时钟为1T
//
//SMOD=0,串口波特率=BRT独立波特率发生器的溢出率/32
//SMOD=1,串口波特率=BRT独立波特率发生器的溢出率/16
//BRTx12=0,BRT独立波特率发生器的溢出率=Fosc/12/(256-BRT)
//BRTx12=1,BRT独立波特率发生器的溢出率=Fosc/(256-BRT)
//uart0波特率=115200bps
//
//p0接4*4矩阵按键
//k9按下,串口发送zk0
//k10按下,串口发送zk1
//k11按下,串口发送zk2
//k12按下,串口发送zk3
//k13按下,串口发送zk4
//k14按下,串口发送zk5
//k15按下,串口发送zk6
//k16按下,串口发送zk7
//k17按下,串口发送zk8
//k18按下,串口发送zk9
//k19按下,串口发送zka
//k20按下,串口发送zkb
//k21按下,串口发送zkc
//k22按下,串口发送zkd
//k23按下,串口发送zke
//k24按下,串口发送zkf
//按键弹起,串口发送zku
//
//STC12C5A60S2 11.0592MHz 收到0xaa,软复位,从用户程序区启动
论坛支持:http://www.eeskill.com
淘宝店铺:http://cepark.taobao.com
作者:eeskill
时间:2017-07-01
******************************************************************/
#include "STC12C5A.h"
#include "matrix_STC12C5A.H"
uchar key_stime_ok=0; // 定时器定时时间标志位
//*************** 函数定义 ******************
void delay1ms(unsigned int j);
void senddata_uart0(uchar dc);
void sendstring_uart0(uchar *dd);
//*************** 主程序 ********************
void main(void)
{
//////////////将这段代码嵌入到程序中////////////////
if((PCON&0x10)==0) //如果POF位=0
{
PCON=PCON|0x10; //将POF位置1
IAP_CONTR|=0x60; //软复位,从ISP监控区启动
}
else
{
PCON=PCON&0xef; //将POF位清零
}
////////////////////////////////////////////////////
TMOD=0x2; //定时器0方式2
TH0=0xa5; //定时时间0.1mS
TL0=0xa5;
TR0=1; //启动定时器
ET0=1; //定时器0中断允许
SCON=0x50; //uart0方式1,允许接收
AUXR=BRTR|S1BRS|BRTx12; //独立波特率发生器时钟为1T,uart0使用并启动独立波特率发生器
BRT=0xfd; //设置独立波特率发生器波特率 115200bps
ES=1; //uart0中断允许
EA=1; //中断总允许
delay1ms(1);
while(1)
{
if(key_stime_ok!=0)
{
key_stime_ok=0;
switch(read_matrixkey())
{
case key15:
{
sendstring_uart0("zk3");
break;
}
case key11:
{
sendstring_uart0("zk2");
break;
}
case key7:
{
sendstring_uart0("zk1");
break;
}
case key3:
{
sendstring_uart0("zk0");
break;
}
case key14:
{
sendstring_uart0("zk7");
break;
}
case key10:
{
sendstring_uart0("zk6");
break;
}
case key6:
{
sendstring_uart0("zk5");
break;
}
case key2:
{
sendstring_uart0("zk4");
break;
}
case key13:
{
sendstring_uart0("zkb");
break;
}
case key9:
{
sendstring_uart0("zka");
break;
}
case key5:
{
sendstring_uart0("zk9");
break;
}
case key1:
{
sendstring_uart0("zk8");
break;
}
case key12:
{
sendstring_uart0("zkf");
break;
}
case key8:
{
sendstring_uart0("zke");
break;
}
case key4:
{
sendstring_uart0("zkd");
break;
}
case key0:
{
sendstring_uart0("zkc");
break;
}
case keyup: //按键弹起
{
sendstring_uart0("zku");
break;
}
default:
{
break;
}
}
}
}
}
void timer0(void) interrupt 1
{
static key_stime_counter=0;
if(++key_stime_counter>=100) //定时100次,定时时间=100*0.1 mS
{
key_stime_counter=0;
key_stime_ok=1; //10ms到,置位标志位
}
}
//uart interrupt
void uart0(void) interrupt 4
{
uchar cdd;
EA=0;
if (RI)
{
RI=0;
cdd=SBUF;
if (cdd==0xaa) //如果接收到0xaa,产生软件复位
{
IAP_CONTR=0x20; //软复位,从用户程序区启动
}
senddata_uart0(cdd+1); //将接收到的数据+1,再发送回去
}
EA=1;
}
//***************************发送数据**************************
void senddata_uart0(uchar dc)
{
SBUF=dc;
while (!TI); //当TI=0时,发送未结束,循环等待
TI=0; //当TI=1时,发送结束,用软件将TI清零
}
//************************发送字符串数据***********************
void sendstring_uart0(uchar *dd)
{
while ((*dd)!=0)
{
senddata_uart0(*dd);
dd++;
}
}
//*************************延时 n*1ms********************
void delay1ms(unsigned int j)
{
unsigned int i;
for (;j>0;j--)
{
for (i=0;i<124;i++)
{;}
}
}