应广单片机处处体现其mini的特性,非常适合做各种方案开发,特别是点灯,什么跑马灯,氛围灯,遥控灯,感应灯,拍拍灯等,用应广都OK。
跑马灯是基础中的基础,我搭了一个框架,要进行扩展或是修改也很容易。不多说,上代码。
#include "extern.h"
/*调试输出开关,关闭之后测试端口不输出了*/
//#define DEBUG
/*1m 标记*/
bit msFlag;
/*us计数*/
byte ucUsCnt;
/*ms 计数*/
byte ucMsCnt;
Word Reload_T16;
/*可以用示波器观察对应端口*/
#ifdef DEBUG
bit US100_OUT :pa.7
bit MS_OUT :pa.6
bit MS10_OUT :pa.0
#endif
byte ucLedst;
BIT COM1 : PA.3;
BIT COM2 : PA.4;
BIT COM3 : PA.6;
BIT COM4 : PA.7;
#define SEG_A COM4
#define SEG_B COM3
#define SEG_C COM2
#define SEG_D COM1
/*中断服务程序*/
void Interrupt(void)
{
pushaf;
if(Intrq.T16)
{
STT16 Reload_T16;
Intrq.T16 = 0;
ucUsCnt++;
if(ucUsCnt>9)
{
ucUsCnt=0;
/*100us*10=1ms*/
msFlag=1;
}
/*100u task,紧急任务放这边,但这里的任务尽量少,
心脏部位,尽量减少干扰,需要保证tick精准*/
#ifdef DEBUG
if(US100_OUT)
{
US100_OUT=0;
}
else
{
US100_OUT=1;
}
#endif
}
popaf;
}
/*T16设置*/
Void Timer16_Init(void)
{
/*向上计数 1600就发生中断 1600/16M=0.0001s=100us,理论设计*/
//Reload_T16 = 32768 - 1600;
/*根据测算(示波器校准),除去误差(约为20个sysclk周期),设置1580这个值可能更准确,
SYSCLK越快,误差越小.从进入中断开始,到重新设置计数器,中间大概需要20个sysclk周期*/
Reload_T16 = 32768 - 1580;
/*设置计数器值*/
STT16 Reload_T16;
/*配置T16 控制寄存器*/
$ T16M IHRC,/1,BIT15;
INTRQ.T16 = 0;
INTEN.T16 = 1;
msFlag=0;
ucUsCnt=0;
}
void ShowBatSt(void)
{
if(ucLedst==0)
{
SEG_A=0;
SEG_B=0;
SEG_C=0;
SEG_D=0;
//ucFlashSegCnt=0;
}
else if(ucLedst==1)
{
SEG_A=1;
SEG_B=0;
SEG_C=0;
SEG_D=0;
//ucFlashSegCnt=0;
}
else if(ucLedst==2)
{
SEG_A=1;
SEG_B=1;
SEG_C=0;
SEG_D=0;
//ucFlashSegCnt=0;
}
else if(ucLedst==3)
{
SEG_A=1;
SEG_B=1;
SEG_C=1;
SEG_D=0;
//ucFlashSegCnt=0;
}
else if(ucLedst==4)
{
SEG_A=1;
SEG_B=1;
SEG_C=1;
SEG_D=1;
//ucFlashSegCnt=20;/*闪烁10s,关机*/
}
else if(ucLedst==6)
{
SEG_A=0;
SEG_B=1;
SEG_C=1;
SEG_D=1;
//ucFlashSegCnt=0;
}
else if(ucLedst==7)
{
SEG_A=0;
SEG_B=0;
SEG_C=1;
SEG_D=1;
//ucFlashSegCnt=0;
}
else if(ucLedst==8)
{
SEG_A=0;
SEG_B=0;
SEG_C=0;
SEG_D=1;
//ucFlashSegCnt=0;
}
else if(ucLedst==9)
{
SEG_A=0;
SEG_B=0;
SEG_C=0;
SEG_D=0;
//ucFlashSegCnt=20;/*闪烁10s,关机*/
}
else
{
}
}
void FPPA0 (void)
{
/*注意,修改了sysclk,Reload_T16要做细微调整,可以试着改动sysclk,
会发现Reload_T16误差变大*/
.ADJUST_IC SYSCLK=IHRC/8,IHRC=16MHz,init_ram,VDD=5V;
.delay 20*2000;
// $ SHOW_EN in ;
$ COM1 OUT,low;
$ COM2 OUT,low;
$ COM3 OUT,low;
$ COM4 OUT,low;
/*初始化T16*/
Timer16_Init();
#ifdef DEBUG
$ US100_OUT out,low;
$ MS_OUT out,low;
$ MS10_OUT out,low;
#endif
ucLedst=0;
Engint;
while (1)
{
/*1ms标记*/
if(msFlag)
{
ucMsCnt++;
if(ucMsCnt>250)
{
/*1ms*10=10ms*/
ucMsCnt=0;
ucLedst++;
if(ucLedst>10)
{
ucLedst=0;
}
ShowBatSt();
/*10mstask 放这里*/
#ifdef DEBUG
if(MS10_OUT)
{
MS10_OUT=0;
}
else
{
MS10_OUT=1;
}
#endif
}
/*1ms task*/
#ifdef DEBUG
if(MS_OUT)
{
MS_OUT=0;
}
else
{
MS_OUT=1;
}
#endif
msFlag=0;
}
}
}
/*creat by zhongvv QQ85547259*/