单片机原理及应用
题目:SPI通信之基于max7219的时钟设计
班级:11007990202
姓名: xxxxx
学号:xxxxxx
一、仿真图:
二、源代码:
(1)、Myhead.h 自定义头文件,包含一些宏定义和函数声明
#define uchar unsigned char
#define uint unsigned int
#define BIT0 1
#define BIT1 1<<1
#define BIT2 1<<2
#define BIT3 1<<3
#define BIT4 1<<4
#define SETCS BIT0
#define SETCLK BIT1
#define SETMOSI BIT2
void delay(uint j); //延时函数申明
void spiwrite(uchar address,uchar dat); //max7219写函数申明
void initialize(); //max7219初始化函数申明
(2)、clock主函数:
#include #include #define T -20222 uchar tick=0; uint table[]={12/*年*/,11/*月*/,8/*日*/,8/*时*/,0/*分*/,0/*秒*/}; uint temp/*读取P0的值*/,flag=5/*标志信号*/; uint *p=table; /************ 中断服务程序 ************/ void timer0() interrupt 1 { ++tick; if(tick==50) { ++table[5]; tick=0; } TH0=T/256; TL0=T%256; if(table[5]==60) { table[5]=0; ++table[4]; } //20ms*50=1s //秒加1 //滴答函数清零重新计时一秒 //装入计数初值 //计时60秒 分钟数加1 if(table[4]==60) { table[4]=0; ++table[3]; if(table[3]==24) { ++table[2]; } table[3]%=24; } } /*************** 加减判定子函数 **************/ void part(uint *a,uint b) //加减判定 { if(temp==0x02) { ++(*a); } else if(temp==0x01) { switch(*a) { case 0: //判断是否减到零 *a=b; break; default: --*a; break; } } } /************ max7219显示子函数 ************/ void display() { if((2<=flag)&&(flag<=4)) { //显示日期 spiwrite(0x01,table[0]/10); spiwrite(0x02,table[0]%10); spiwrite(0x03,15); spiwrite(0x04,table[1]/10); spiwrite(0x05,table[1]%10); spiwrite(0x06,15); spiwrite(0x07,table[2]/10); spiwrite(0x08,table[2]%10); delay(10000); } else if((0<=flag)&&(flag<=1)||flag==5) //显示时间 { spiwrite(0x01,table[3]/10); spiwrite(0x02,table[3]%10); spiwrite(0x03,15); spiwrite(0x04,table[4]/10); spiwrite(0x05,table[4]%10); spiwrite(0x06,15); spiwrite(0x07,table[5]/10); spiwrite(0x08,table[5]%10); } } /****************** 时间设定功能模块函数 *******************/ void change() //扫描及确定加减 { temp=P0; //读取加减按键的值 temp&=(BIT1|BIT0); //取p0口前两位 delay(9000); switch(flag) { case 0: part(p+4,59); break; //分 case 1: part(p+3,23); break; //时 case 2: if(temp==0x01&&table[2]==0x01) //修正语句 不加该语句减到1是无法继续减 table[2]=31; part(p+2,31); break; //日 case 3: if(temp==0x01&&table[1]==0x01) table[1]=13; part(p+1,12); break; //月 case 4: part(p,99); break; //年 } if(table[4]==60) { ++table[3]; } if(table[3]==24) { ++table[2]; } switch(table[1]) { case 2: ; case 4: ; //min加到60,hour+1 //计满24小时,day加1 //大小月修正函数 //case2、4、6、9、11均执行case11的语句小月 case 6: ; case 9: ; case 11: if(table[2]==31) { ++table[1]; } table[2]%=31; break; default: if(table[2]==32) { ++table[1]; //大月补偿 } table[2]%=32; break; } if(table[1]==13) { ++table[0]; } table[3]%=24; table[4]%=60; table[1]%=13; if(table[2]==0) ++table[2]; //限值函数 if(table[1]==0) ++table[1]; } /*************** 主函数 ************/ void main() { //初始化 TMOD=0X01; //软件启动 定时器0 定时 TH0=T/256; TL0=T%256; ET0=1; EA=1; TR0=1; initialize(); //初始化max7219 while(1) { display(); 么叫出口参数? temp=P0; temp&=BIT2; if(temp==0x00) { flag++; flag%=6; while(temp==0x00) //功能键 //什么叫入口参数 什 { temp=P0; temp&=BIT2; } } change(); //时间设定 扫描模块 switch(flag) //功能指示灯函数 { case 0: P2=~BIT0; break; //调分钟指示 case 1: P2=~BIT1; break; //调小时 case 2: P2=~BIT2; break; //调号数 case 3: P2=~BIT3; break; //调月份 case 4: P2=~BIT4; break; //调年 default : P2=0xff; break; //正常显示 } } } (3)max7219驱动程序: #include #include /********** 延时子函数 大约延时2j+5us **********/ void delay(uint j) { while(--j); } /**************** spi写入子函数 ****************/ void spiwrite(uchar address,uchar dat) //向max7219写入数据 { uint i; uchar temp; P1&=(~SETCS); //p1口作为spi通信口 拉低cs准备通信 for(i=0;i<8;i++) //写入地址 { P1&=(~SETCLK); //拉低clk delay(10); temp=address&0x80; //取地址最高位 if(temp==0x80) { P1|=SETMOSI; //写入数据0 } else { P1&=(~SETMOSI); //写入数据1 } delay(10); P1|=SETCLK; //上升沿写入数据 address<<=1; //地址左移一位 } for(i=0;i<8;i++) //写入要传送的数据 { P1&=~SETCLK; delay(10); temp=dat&0x80; if(temp==0x80) { P1|=SETMOSI; } else { P1&=(~SETMOSI); } delay(100); P1|=SETCLK; dat<<=1; } P1|=SETCS; delay(100); } /************** max7219初始化子函数 **************/ void initialize() { P1=0x07; spiwrite(0x0c,0x00); delay(100); spiwrite(0x0c,0x01);//正常工作 spiwrite(0x09,0xff);//全译码 译码选择控制某一位为1则译码 0不译码 spiwrite(0x0a,0x0f); //亮度调节 spiwrite(0x0b,0x07); //显示位数 spiwrite(0x0f,0x00); //退出测试 } 因篇幅问题不能全部显示,请点此查看更多更全内容