/***********STC12C5A60S2单片机驱动74595 8位LED显示实验*************
程序功能:上位机配套的8位数码管下位机代码
开发环境:Keil4
硬件环境:CEPARK多功能开发学习板/实验箱(2017版),STC12C5A60S2,11.0592M晶振
接线说明:单片机P20~P22口接底板JP26,具体接线为:P20-STCP,P21-SHCP,P22-DS
跳线说明:无
实验现象: 打开上位机软件,打开相应串口,注意串口号要选对,注意晶振为11.0592M
点击打开8位数码管界面, 点亮上位机上对应段,底板上8位数码管对应的段也被点亮。
上位机相关:
//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
//STC12C5A60S2 11.0592MHz 收到0xaa,软复位,从用户程序区启动
论坛支持:http://www.ippipp.com
淘宝店铺:http://cepark.taobao.com
作者:eeskill
时间:2017-07-01
******************************************************************/
#include "STC12C5A.h"
#define rclk p20 //存储寄存器时钟 (74595:12脚) 电路板STCP
#define srclk p21 //移位寄存器时钟 (74595:11脚) 电路板SHCP
#define ser p22 //串行数据口 (74595:14脚) 电路板DS
//oe:输出允许 L:允许输出;H:禁止输出;(74595:13脚)
//srclr:移位寄存器清零(L:清零)(74595:10脚)
uchar smg[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
uchar code smg_text[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,};
uchar code smg_bit[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0xff,};
uchar d;
//*************** 函数定义 ******************
void delay1ms(unsigned int j);
void senddata_74595(uchar SendData);
void senddata_uart0(uchar dc);
void led_display(void);
//*************** 主程序 ********************
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中断允许
rclk=0; //产生锁存时钟
senddata_74595(0x00);
senddata_74595(0x00);
rclk=1;
delay1ms(1000);
for(d=0;d<8;d++)
{
rclk=0;
senddata_74595(smg_bit[8]);
senddata_74595(smg_text[d]);
rclk=1;
delay1ms(1500);
}
rclk=0; //产生锁存时钟
senddata_74595(0x00);
senddata_74595(0x00);
rclk=1;
EA=1; //中断总允许
while(1)
{
}
}
void timer0(void) interrupt 1
{
static key_stime_counter=0;
if(++key_stime_counter>=20) //定时20次,定时时间=20*0.1 mS
{
key_stime_counter=0;
led_display();
}
}
//uart interrupt
void uart0(void) interrupt 4
{
uchar tc[9];
uint m=0;
uint count=0;
EA=0;
if(RI)
{
while(count<10000)
{
if(RI)
{
RI=0;
if(m<9)
{
tc[m]=SBUF;
}
m++;
count=0;
}
else //循环等待10000次,没有接收到数据退出while循环
{
count++;
}
}
}
if(1==m)
{
if(0xaa==tc[0])
{
IAP_CONTR=0x20; //软复位,从用户程序区启动
}
else
{
senddata_uart0(tc[0]+1); //将接收到的数据+1,再发送回去
}
}
else if(9==m)
{
if(0x08==tc[0])
{
for(count=0;count<8;count++)
{
smg[count]=~tc[count+1];
}
}
}
EA=1;
}
//***************************发送数据**************************
void senddata_uart0(uchar dc)
{
SBUF=dc;
while (!TI); //当TI=0时,发送未结束,循环等待
TI=0; //当TI=1时,发送结束,用软件将TI清零
}
//***********************74595发送函数************************
void senddata_74595(uchar SendData)
{
uchar i;
for(i=0;i<8;i++)
{
if((SendData&0x80)==0) //先发送高位,后发送低位
{
ser=0;
}
else
{
ser=1;
}
srclk=0;
SendData=SendData<<1; //数据左移一位
srclk=1;
}
}
void led_display(void)
{
static uchar st=0;
rclk=0;
senddata_74595(smg_bit[st]);
senddata_74595(smg[st]);
rclk=1;
st=(++st)%8;
}
//*************************延时 n*1ms********************
void delay1ms(unsigned int j)
{
unsigned int i;
for (;j>0;j--)
{
for (i=0;i<124;i++)
{;}
}
}