流水灯四种效果:#include <hidef.h> /* common defines and macros */ #include <stdlib.h>#include <mc9s12xdp512.h> /* derivative information */ #pragma LINK_INFO DERIV ATIVE "mc9s12xdp512"#include "main_asm.h" /* interface to the assembly module */ unsigned char temp;//unsigned char pa @0x200;//unsigned char pb @0x202;unsigned char key;static void delay(void) {volatile unsigned long i;for(i=0;i<100000;i++);}static unsigned char random;static void Random(void) {random = (unsigned char)rand();}void effect1() {unsigned char c;for(c=0;c<=6;c++) {delay();PORTB = ~(1<<c);}for(c=7;c>=1;c--) {delay();PORTB = ~(1<<c);}}void effect2() {unsigned char c;for(c=0;c<=6;c++) {delay();PORTB = ~(3<<c);}for(c=7;c>=1;c--) {delay();PORTB = ~(3<<c);}}void effect3() {unsigned char c,t=0xfe;for(c=0;c<=7;c++) {PORTB = t;delay();t<<=1;}}void effect4() {unsigned char c,t=0;for(c=0;c<=7;c++) {PORTB=t;delay();t = (t<<1)+1;;}}void main(void) {unsigned char x;DDRA=0xf0;DDRB=0xff;for(;;) {x=PORTA&0x03;switch(x) {case 0:effect1(); break;case 1:effect2(); break;case 2:effect3(); break;case 3:effect4(); break;}}/* wait forever *//* please make sure that you never leave this function */ }//行列反转法unsigned char key_scan() //键盘扫描函数{ unsigned char x,row=4,col=4,key=16;PUCR|=0x01; //等同于PUCR=PUCR|0x01,PUCR寄存器的第0位设置为1,即允许PORTA端口的上拉电阻。
PUCR寄存器的解释参见书本P113DDRA=0x0f; //行线PA0-PA3设置为输出,列线PA4-PA7设置为输入DDRA寄存器知识参见书本P113数据方向寄存器PORTA=0xf0; //0bxxxx0000,四条行线PA0-PA3输出四个0,相当于四条行线接地x=PORTA&0xf0; //读取四条列线的值,并保留高4位,清除低4位的值if(x!=0xf0) //如果四条列线不全为1,则说明有按键按下{switch(x){case 0xe0:col=1;break; //按键在第1列case 0xd0:col=2;break; //按键在第2列case 0xb0:col=3;break; //按键在第3列case 0x70:col=4;break; //按键在第4列}//以下开始行列反转,输入变输出,输出变输入。
即行线PA0-PA3设为输入,列线PA4-PA7设为输出DDRB=0xf0; //行线PA0-PA3设为输入,列线PA4-PA7设为输出PORTA=0x0f;//0b0000xxxx,四条列线PA4-PA7输出四个0,相当于四条列线接地x=PORTA&0x0f //读取四条行线的值,并保留低4位,清除高4位的值if(x!=0x0f)//如果四条行线不全为1,则说明有按键按下{ switch(x){case 0x0e:row=1;break; //按键在第1行case 0x0d:row=2;break; //按键在第2行case 0x0b:row=3;break; //按键在第3行case 0x07:row=4;break; //按键在第4行}key=(row-1)*4+col-1; //求出键号:0-15的整数}}return key; //如果没有按键按下,则函数返回的key=16;}main(){ unsigned char keyno;while(1){keyno=key_scan(); //调用键盘扫描函数获取是否有按键按下,是哪个按键按下if(keyno<16) //keyno<16有按键按下,keyno=16则表明无按键按下switch(keyno){ case 0: //每一个按键按下后要实现什么功能,程序写在这。
case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:}}}//行扫描法1unsigned char key_scan(){ unsigned char x,i,temp,row=4,col=4,key=16;//PUCR|=0x01; //等同于PUCR=PUCR|0x01,PUCR寄存器的第0位设置为1,即允许PORTA端口的上拉电阻。
PUCR寄存器的解释参见书本P113DDRA=0x0f; //行线PA0-PA3设置为输出,列线PA4-PA7设置为输入DDRA寄存器知识参见书本P113数据方向寄存器PORTA=0xf0; //0bxxxx0000,四条行线PA0-PA3输出四个0,相当于四条行线接地x=PORTA&0xf0; //读取四条列线的值,并保留高4位,清除低4位的值if(x!=0xf0) //如果四条列线不全为1,则说明有按键按下{switch(x){case 0xe0:col=1;break; //按键在第1列case 0xd0:col=2;break; //按键在第2列case 0xb0:col=3;break; //按键在第3列case 0x70:col=4;break; //按键在第4列}//以下开始从第1行到第4行逐行判断按键是否在该行temp=0b11111110;for(i=1;i<=4;i++) //i代表正在判断按下的按键是否是在第i行{PORTA=temp; //第i行所在的行线输出0,其他三条行线输出1x=PORTA&0xf0;//读取四条列线的值,并保留高4位,清除低4位的值if(x!=0xf0) //如果四条列线不全为1,则说明按键就在第i行,否则表明按键不在该行,则准备扫描下一行{ row=i;key=(row-1)*4+col-1; //求出按键return key; //退出key_scan函数}temp=(temp<<1) +1; //按键不在该行,则改变temp的值,为扫描下一行做准备。
}}return key; //如果没有按键按下,程序才回执行到这,此时key为初值16;}main(){ unsigned char keyno;while(1){keyno=key_scan(); //调用键盘扫描函数获取是否有按键按下,是哪个按键按下if(keyno<16) //keyno<16有按键按下,keyno=16则表明无按键按下switch(keyno){ case 0: //每一个按键按下后要实现什么功能,程序写在这。
case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:}}}PWM模块:void PWM_Init(void){PWME = 0x00; //禁止PWM模块PWMPRCLK = 0x06; //CLOCKA的预分频设置为6,分频系数64 PWMSCLA = 125; //SA的分频因子设置为125,分频系数250PWMCLK = 0x01; //通道0选择SA作为PWM时钟PWMPER0 = 200; //通道0周期寄存器设置为200PWMDTY0 = 100; //通道0占空比寄存器设置PWMPOL = 0x01; //PWM输出先为高电平,之后变为低电平PWMCAE = 0x00; //左对齐输出PWMCTL = 0x00; //不级联PWME = 0x01; //使能PWM通道0}void main(void){byte LedCnt=0;setbusclock();PWM_Init();for(;;){}}void interrupt 0 _Startup(void) {INIT_SP_FROM_STARTUP_DESC(); //初始化堆栈指针SPmain();}输入捕捉(求占空比):#include <hidef.h> /* common defines and macros */#include "derivative.h" /* derivative-specific definitions */ #include<MC9S12XS128.h>#include<string.h>unsigned int x,y;unsigned long int n,Th,Tl;unsigned char t,a;void TIM_Init(){TSCR1=0x00;TSCR2=0x84;TIOS_IOS0=0;TCTL4=0x01;TIE_C0I=0x01;TSCR1|=0x80; //启动定时器}#pragma CODE_SEG_NEAR_SEG NONBANKEDvoid interrupt 8 TIM_Tie(){y=x;x=TC0;if(TCTL4==0x02)Th=(x-y+(n<<16))*t;if(TCTL4==0x01)Tl=(x-y+(n<<16))*t;TFLG1|=0x01; //写1清零n=0;a=TCTL4;a=~a&0x03;TCTL4=a;}#pragma CODE_SEG_NEAR_SEG NONBANKEDvoid interrupt 16 TIM_Tof(){n++;TFLG2|=0x80; //写1清零}void main(void) {TIM_Init();for(;;) {// _FEED_COP(); /* feeds the dog */} /* loop forever *//* please make sure that you never leave main */}电子时钟(包含串口通信和定时器)://知识点1: 串口初始化、串口数据收发及数据处理// 2: 定时器如何实现指定的定时时间#include <hidef.h>#include <string.h>#include "IO_Map.h"//#include "derivative.h"// global variables definitionsstatic int waittime = 5;static unsigned char redButtonDown = FALSE, blueButtonDown = FALSE;static long absoluteTime = 0;unsigned int count=0;unsigned char time[3]={0,0,0};unsigned char cmd_buf[8];unsigned char pos=0;static const char segs[]={~0x3f,~0x06,~0x5b,~0x4f,~0x66,~0x6d,~0x7d,~0x07,~0x7f,~0x6f}; //static const char //segss[]={~0xbf,~0x86,~0xdb,~0xcf,~0xe6,~0xed,~0xfd,~0x87,~0xff,~0xef}; //#pragma CODE_SEG DEFAULTstatic void WriteToSCI0(const char *text){while (*text != '\0'){while (!(SCI0SR1 & 0x80)); // wait for output buffer emptySCI0DRL = *text++;}}void execute_cmd(){ unsigned char tmp[3];if ((cmd_buf[0]=='t')&&(pos==7)){tmp[0]=(cmd_buf[1]-'0')*10+cmd_buf[2]-'0';tmp[1]=(cmd_buf[3]-'0')*10+cmd_buf[4]-'0';tmp[2]=(cmd_buf[5]-'0')*10+cmd_buf[6]-'0';if ((tmp[0]<24)&&(tmp[1]<60)&&(tmp[2]<60)){time[0]=tmp[0];time[1]=tmp[1];time[2]=tmp[2];}}pos=0;}//*#pragma CODE_SEG __NEAR_SEG NON_BANKEDvoid interrupt 20 SCI0_ISR(void){unsigned char rc;rc = SCI0SR1; // dummy read to clear flagsrc = SCI0DRL; // data readif(rc!=0x0d)cmd_buf[pos++]=rc;elseexecute_cmd();SCI0DRL = rc;}#pragma CODE_SEG __NEAR_SEG NON_BANKEDvoid setbusclock(void){CLKSEL=0X00; // disengage PLL to systemPLLCTL_PLLON=1; // turn on PLLSYNR=0x00 | 0x01; // VCOFRQ[7:6];SYNDIV[5:0]// fVCO= 2*fOSC*(SYNDIV + 1)/(REFDIV + 1) fVCO= 2*fOSC*2/2=2*fOSC// fPLL= fVCO/(2 × POSTDIV) fPLL= fVCO;// fBUS= fPLL/2 fBUS= fPLL/2=fosc;// VCOCLK Frequency Ranges VCOFRQ[7:6]// 32MHz <= fVCO <= 48MHz 00// 48MHz < fVCO <= 80MHz 01// Reserved 10// 80MHz < fVCO <= 120MHz 11REFDV=0x80 | 0x01; // REFFRQ[7:6];REFDIV[5:0]// fREF=fOSC/(REFDIV + 1)// REFCLK Frequency Ranges REFFRQ[7:6]// 1MHz <= fREF <= 2MHz 00// 2MHz < fREF <= 6MHz 01// 6MHz < fREF <= 12MHz 10// fREF > 12MHz 11// pllclock=2*osc*(1+SYNR)/(1+REFDV)=32MHz;POSTDIV=0x00; // 4:0, fPLL= fVCO/(2xPOSTDIV)// If POSTDIV = $00 then fPLL is identical to fVCO (divide by one)._asm(nop); // BUS CLOCK=16M_asm(nop);while(!(CRGFLG_LOCK==1)); //when pll is steady ,then use it;CLKSEL_PLLSEL =1; //engage PLL to system;}void interrupt 26 MDC_ISR(void) //定时器MDC模块中断服务程序,当定时时间到时自动执行该程序{MCFLG|=0X80;//MCFLG_MCZF=1;count++;if (count%10==0){count=0;time[2]++;if(time[2]>=60){time[2]=0;time[1]++;if(time[1]>=60){time[1]=0;time[0]++;if(time[0]>=24)time[0]=0;}}}}//*/#pragma CODE_SEG DEFAULTstatic void SCI0Init(void) {SCI0BDL = (unsigned char)((16000000UL /* OSC freq */ / 2) / 9600 /* baud rate */ / 16 /*factor*/);SCI0CR2 = 0x2C;}void MDC_Init() {unsigned char i;MCCTL=0b11101111; //MCZI=1,MODMC=1,RDMCL=1,ICLAT=0,FLMC=1,MCEN=0,MCPR1-0=0b11(16分频) MCCNT=10000; //定时10000us=10ms//MCCTL_MCEN=1;}void main(void) {unsigned char tmp;DDRA = 0xFF;DDRB = 0xFF;DDRE = 0xFF;DDRP = 0xFF;DDRM = 0xFF;DDRT = 0xFF;PORTA =0xFF;PORTB =0xFF;PORTE =0xFF;PTP =0xFF;PTM =0xFF;PTT =0xFF;setbusclock();//startTimeBase();SCI0Init();MDC_Init();WriteToSCI0("\n\n*** Timer Demo ***\n"); WriteToSCI0("\nEnter 't123456' to set time to 12:34:56\n"); INTCR_IRQEN=0; //屏蔽IRQ中断EnableInterrupts; //使能全局中断for (;;){if(time[2]!=tmp) //if 秒钟数有更新{tmp=time[2];PORTA = segs[time[0]/10];PORTB = segs[time[0]%10]&0x7f;PORTE = segs[time[1]/10];PTP = segs[time[1]%10]&0x7f;PTM = segs[time[2]/10];PTT = segs[time[2]%10];}}}。