AVR mega16 SPI 双机通讯 程序代码
- 格式:doc
- 大小:35.00 KB
- 文档页数:7
A TMEGA16端口扩展例子及源代码青岛科技大学树立学院王泽华说明:1、数码管为共阳极。
2、HC595两片,第一片锁存段码,第二片锁存位码。
3、外部晶振8MHz该图可放大观看,例如拷贝到剪切板,然后复制到画图软件中。
这样比较清楚4、PROTEUL下溶思位的选择如下图所示。
源代码如下:可直接拷贝编译运行。
/*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */#define F_CPU 8000000UL/* 定义SPI端口数据方向寄存器*/#define DD_SS 4#define DD_MOSI 5#define DD_MISO 6#define DD_SCK 7/* 定义SPI端口数据寄存器*/#define DR_SS 4#include <avr/io.h>#include <util/delay.h>/* 共阳极段码*/const unsigned char SEG_CODE[]={0x03,0x9F,0x25,0x0D,0x99,0x49,0x41,0x1F,0x01,0x09}; /* 位码*/const unsigned char BIT_CODE[]={0x80,0x40,0x20,0x10};/* SPI端口初始化*/void SPI_master_init(){/* 定义SPI主机,SS线,MOSI线,SCK线为输出*/DDRB = (1<<DD_SS) | (1<<DD_MOSI) | (1<<DD_SCK);/* 打开SPI端口,设本机为SPI主机,SCK=FOSC/16 */SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0);/* SPI工作于MODE4 */SPCR |= (1<<CPOL) | (1<<CPHA);}/* 传输,特别用于只发不收,例如2片HC595控制数码管显示,每次传输两字节,第一字节为位码,第二字节为段码*/void SPI_master_send(char *pData, int iDataLen){int i;char temp;/* 拉低SS引脚,告之从机,开始数据传输*/PORTB &= ~( 1<<DR_SS );/* 发送数据*/for( i=0; i<iDataLen; i++){SPDR = pData[i];/* 等待发送完成*/while( !( SPSR & (1<<SPIF) ) );/* 清标志寄存器SPIF WCOL */temp = SPSR;temp = SPDR;}/* 拉高SS引脚,完成一次通讯,对HC595,拉高后595将移位寄存器数据锁存入数据寄存器*/PORTB |= ( 1<<DR_SS );}int main(){unsigned char i;char cData[2];/* SPI端口初始化*/SPI_master_init();while(1){for(i=0; i<4; i++){/* 先关闭数码管,消隐*/cData[0] = BIT_CODE[i];cData[1] = 0xFF;SPI_master_send(cData,2);/* 发送显示的数据*/cData[0] = BIT_CODE[i];cData[1] = SEG_CODE[i];SPI_master_send(cData,2);_delay_ms(4);}}}。
/*********************************************************************MCU: ATmega16外部晶振: 8MHz程序功能: 4*4鍵盤識別,LED七段數碼管顯示,密碼功能模塊,直流電機正反轉控制 AD轉換模塊, 模擬比較器,外部中斷應用,12864液晶,C/T0硬件設計:參考PROTUES硬件仿真電路調試:所有程序主要功能都軟硬件仿真通過,實際使用時要根據需要加入可靠性。
編譯環境: ICC AVRDesign by: wdw********************************************************************/#include<iom16v.h>#include<macros.h>#include<math.h>#define uchar unsigned char#define uint unsigned int#define SET_1(a,b) a|=bit(b) //將寄存器a的第b位置1#define CLR_0(a,b) a&=~bit(b) //將寄存器a的第b位清0#program date code:const date[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,//共陽數據;0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};#program duan code:const duan[]={0x20,0x10,0x08,0x04,0x02,0x01}; //段選;char adchannel;int dispbuf[]={0,0,0,0,0,0,}; //顯示緩存;uchar securbuf[]={0,0,0,0,0,}; //5位密碼緩存;/********************************************************************名稱:ms延時子函數功能:延時指定的ms*********************************************************************/void delayms(int ms){int i,j;for(i=ms;i>0;i--){for(j=1722;j>0;j--); //8M时改为1141;} //12M时为1722;}/*******************************************************************名稱:us延時子程序功能:延時指定的us********************************************************************/void delayus(uchar us){for(us;us<0;us--);{} //12M时单位T为1.45US}/********************************************************************单参数LED 显示硬件连接:数据PORTC-----D7~D0段选PORTD-----D7~D4*********************************************************************/void LEDShow(long int shownum){uchar i,tmp,curnum;long int tmpnum;tmp = 0xfb;tmpnum = shownum;for(i=0;i<6;i++) //显示的位数为5{curnum = tmpnum % 10;tmpnum = tmpnum / 10;PORTD = tmp;PORTC = date[curnum];delayus(1);tmp = (tmp << 1) + 0x01; //补上移位造成的最右位为0;}}/*******************************************************名稱:七段LED共陽數碼管,在指定数位上显示指定的数,双参数功能:在指定的位置上顯示制定的數;硬件連接:PC口複用控制段選和位選,有2片573進行數據鎖存;*******************************************************/void show(uchar dat,uchar num) //六位七段數碼管顯示程序OK; {PORTC=date[dat];PORTD|=BIT(0);PORTD&=~BIT(0); //送數據;delayus(2);PORTC=0X00;delayus(1);PORTC=duan[num];PORTD|=BIT(1);delayus(2);PORTD&=~BIT(1);delayus(2);} //送選通信號;/************************************************************名稱:MCU端口初始化功能:設置MCU端口初始方向為輸出初始狀態為低*************************************************************/ void Gpioinit0(){DDRA=0XFF;PORTA=0X00;DDRB=0XFF;PORTB=0X00;DDRC=0XFF;PORTC=0X00;DDRD=0XFF;PORTD=0X00;}/***********************************************************名稱:MCU端口初始化功能:設置MCU端口初始為輸出初始狀態為高************************************************************/ void Gpioinit1(){DDRA=0Xff;PORTA=0XFF;DDRB=0xff;PORTB=0XFF;DDRC=0xff;PORTC=0XFF;DDRD=0xff;PORTD=0XFF;}/**************************************************名稱:單端口測試輸入:測試PC的任意端口號0~7功能:週期改變一個端口的電平**************************************************/void IOtest(uchar num){DDRC|=BIT(num);// while(1)// {PORTC|=BIT(num);delayms(50);PORTC&=~BIT(num);delayms(50);// }}/*************************************************名稱:按鍵動作檢測子程序。
//基于ATMEGA16的SPI驱动TLC2543的AD采集、DS18B20温度采集、及通信程序,proteus仿真通过,编译环境,winavr09#include<avr/io.h>#include<util/delay.h>//#include<stdio.h>//#include<utils/iomacros.h>//#include <eeprom.h>//#include<sig-avr.h>//#include<util/twi.h>#include<avr/interrupt.h>//#include<math.h>#define sbi(sfr,bit) (_SFR_BYTE(sfr)|=_BV(bit))#define cbi(sfr,bit) (_SFR_BYTE(sfr)&=~_BV(bit))#define uchar unsigned char#define uint unsigned intunsigned int temple;//得到的温度值unsigned char temp[2]={0,0}; //存放DS18B20的温度寄存器值unsigned char f;uchar weihao[11]={0x0c,0x1c,0x2c,0x3c,0x4c,0x5c,0x6c,0x7c,0x8c,0x9c,0xac};uint shuju[11]={0};uchar jsu;/*****************************SPI初始化*******************************************/unsigned char SPI_MasterTransmit(char cData) //主机数据发送{SPDR = cData; // 启动数据传输while(!(SPSR & (1<<SPIF))); //等待传输结束return SPDR;}/**************************18B20复位**********************************************/void ow_reset(void){uchar presence;sbi(DDRD,PD4);cbi(PORTD,PD4);_delay_us(490);//至少480微秒, leave it low for 501ussbi(PORTD,PD4); // 拉高_delay_us(35);cbi(DDRD,PD4);// 等待36uspresence = PIND; // 读总线信号_delay_us(150); // 0X00= DS18B20 ready, 0X10= busy}/************************读取一个字节*********************************************/uint read_byte(void){uint8_t temp,k,n;temp=0;for(n=0;n<8;n++){//sbi(DDRD,PD4);cbi(PORTD,PD4);//拉低_delay_us(4);sbi(PORTD,PD4);//拉高cbi(DDRD,PD4);k=(PIND&(1<<4)); //读数据,从低位开始if(k)temp|=(1<<n);elsetemp&=~(1<<n);_delay_us(90); //60~120us,实际约90usDDRD|=(1<<4);_delay_us(4);//位之间间隔}return (temp);}/******************向18B20写一个字节**********************************************/void write_byte(char val){uchar i;for (i=8; i>0; i--) //写一个字节{sbi(DDRD,PD4); // 拉低,开始写时间间隙cbi(PORTD,PD4);_delay_us(4);PORTD =(val&0x01)<<4;_delay_us(96); //保持sbi(PORTD,PD4);_delay_us(4);val>>=1;}}/********************读取温度*****************************************************/void Read_Temperature(void){int i;ow_reset();_delay_us(4);//延时4uswrite_byte(0xCC); //Sk_nop_();ip ROM,跳过序列号_delay_us(4);write_byte(0xBE); // read register_delay_us(8);//延时8ustemp[0]=read_byte(); //读取低字节temp[1]=read_byte(); //读取高字节i=temp[1];i<<=8; //把b放到高八位上去i|=temp[0]; //将a放到底八位上去// i&=0x07ff;if( (temp[1]&0x08)){temple=~i+1; //如果为负温则去除其补码f = 0; //表示温度为负数}else{temple=i;f = 1; //表示温度为正数}}/**********************************18B20初始化************************************/void tmstart (void) //初始化{ow_reset(); //复位_delay_us(12); //延时write_byte(0xCC); //跳过序列号命令write_byte(0x44); //发转换命令 44H,}/*********************************************************************************/void temp_init (void){tmstart();//1820初始化_delay_us(600);Read_Temperature();_delay_us(12);tmstart();_delay_us(600);Read_Temperature();_delay_us(12);}void SPI_MasterInit(void)// 初始化为主机{//DDRB = (1<<DDB5)|(1<<DDB7); //设置 MOSI和 SCK为输出,其他为输入//SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);// 使能 SPI主机模式,设置时钟速率为fck/16SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);}/***************************串口初始化***********************************************/void uart_init(void){UCSRA = 0X00; //不倍速,异步模式基于atmega16的SPI驱动TLC2543的ad采集以及ds18b20温度采集及通信程序.txt UCSRC=(1<<URSEL)|(1<<USBS)|(3<<UCSZ0);//8bit + 2stopUBRRH = 0X00;//band 9600,8M UBRRL = 0X33;UCSRB = (1<< RXEN)|(1<<TXEN);//使能}void sendchar(unsigned char data)//串口以查询方式发送数据{while(!(UCSRA & (1<<UDRE)));UDR=data;}void getschar(void)//接收一个字节{while(!(UCSRA &(1<<RXC)));jsu = UDR;}/**************************dian ya cai ji*******************************/void adc_init(void){uchar i,j,adch,adcl;uint k;DDRB = 0xb8;_delay_ms(10);for(i=0;i<11;i++){for(j=0;j<3;j++){SPI_MasterInit();sbi(PORTB,PB3);_delay_ms(10);cbi(PORTB,PB3);_delay_ms(10);adcl=SPI_MasterTransmit(weihao[i]);adch=SPI_MasterTransmit(weihao[i]);_delay_ms(10);sbi(PORTB,PB3);k=adch<<8;k|=adcl;}shuju[i]=k;}}/********************************duan kou chu shi hua ***************************/void port_init(void){DDRC = 0X00;PORTC = 0X1F;sbi(DDRD,PD3);cbi(PORTD,PD3);}/******************************** main *******************************/int main (void){uchar a,s[2];port_init();uart_init();while(1){adc_init();temp_init();getschar();s[0]=jsu;getschar();s[1]=jsu;if((s[0]==0x30)&(s[1]==0x31)){sbi(PORTD,PD3);sendchar(PINC);for(a=0;a<11;a++){基于atmega16的SPI驱动TLC2543的ad采集以及ds18b20温度采集及通信程序.txtsendchar(shuju[a]);sendchar(shuju[a]>>8);}sendchar(temple);sendchar(temple>>8);cbi(PORTD,PD3);}}}。
枯藤老树昏鸦,小桥流水人家,古道西风瘦马。
夕阳西下,断肠人在天涯。
/*********************************************************************MCU: ATmega16外部晶振:8MHz程序功能:4*4鍵盤識別,LED七段數碼管顯示,密碼功能模塊,直流電機正反轉控制AD轉換模塊, 模擬比較器,外部中斷應用,12864液晶,C/T0硬件設計:參考PROTUES硬件仿真電路調試:所有程序主要功能都軟硬件仿真通過,實際使用時要根據需要加入可靠性。
編譯環境:ICC AVRDesign by: wdw********************************************************************/#include<iom16v.h>#include<macros.h>#include<math.h>#define uchar unsigned char#define uint unsigned int#define SET_1(a,b) a|=bit(b) //將寄存器a的第b位置1#define CLR_0(a,b) a&=~bit(b) //將寄存器a的第b位清0#program date code:const date[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,//共陽數據;0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};#program duan code:const duan[]={0x20,0x10,0x08,0x04,0x02,0x01}; //段選;char adchannel;int dispbuf[]={0,0,0,0,0,0,}; //顯示緩存;uchar securbuf[]={0,0,0,0,0,}; //5位密碼緩存;/********************************************************************名稱:ms延時子函數功能:延時指定的ms*********************************************************************/void delayms(int ms){int i,j;for(i=ms;i>0;i--){for(j=1722;j>0;j--); //8M时改为1141;} //12M时为1722;}/*******************************************************************名稱:us延時子程序功能:延時指定的us********************************************************************/void delayus(uchar us){for(us;us<0;us--);{} //12M时单位T为1.45US}/********************************************************************单参数LED 显示硬件连接:数据PORTC-----D7~D0段选PORTD-----D7~D4*********************************************************************/void LEDShow(long int shownum){uchar i,tmp,curnum;long int tmpnum;tmp = 0xfb;tmpnum = shownum;for(i=0;i<6;i++) //显示的位数为5{curnum = tmpnum % 10;tmpnum = tmpnum / 10;PORTD = tmp;PORTC = date[curnum];delayus(1);tmp = (tmp << 1) + 0x01; //补上移位造成的最右位为0;}}/*******************************************************名稱:七段LED共陽數碼管,在指定数位上显示指定的数,双参数功能:在指定的位置上顯示制定的數;硬件連接:PC口複用控制段選和位選,有2片573進行數據鎖存;*******************************************************/void show(uchar dat,uchar num) //六位七段數碼管顯示程序OK;{PORTC=date[dat];PORTD|=BIT(0);PORTD&=~BIT(0); //送數據;delayus(2);PORTC=0X00;delayus(1);PORTC=duan[num];PORTD|=BIT(1);delayus(2);PORTD&=~BIT(1);delayus(2);} //送選通信號;/************************************************************名稱:MCU端口初始化功能:設置MCU端口初始方向為輸出初始狀態為低*************************************************************/ void Gpioinit0(){DDRA=0XFF;PORTA=0X00;DDRB=0XFF;PORTB=0X00;DDRC=0XFF;PORTC=0X00;DDRD=0XFF;PORTD=0X00;}/*********************************************************** 名稱:MCU端口初始化功能:設置MCU端口初始為輸出初始狀態為高************************************************************/ void Gpioinit1(){DDRA=0Xff;PORTA=0XFF;DDRB=0xff;PORTB=0XFF;DDRC=0xff;PORTC=0XFF;DDRD=0xff;PORTD=0XFF;}/**************************************************名稱:單端口測試輸入:測試PC的任意端口號0~7功能:週期改變一個端口的電平**************************************************/void IOtest(uchar num){DDRC|=BIT(num);// while(1)// {PORTC|=BIT(num);delayms(50);PORTC&=~BIT(num);delayms(50);// }}/*************************************************名稱:按鍵動作檢測子程序。
之前做双机通信的时候,可是把我给弄惨了,怎么做都不行,从机接到的数据一至是零。
在网上搜例程,然后copy到自己的程序里,居然运行结果还是一样。
可谓一个纠结啊。
结果还是自己给弄出来了。
下面就是我的程序和电路接口。
、电路接口(Protues仿真)Pb4-pb7全部对接即可,那一个断码管是接在pc口上,如图。
PS:在PC端口和断码管之间需接200Ω电阻,为了简便,这里不接。
其中左边的为主机,右边的为从机。
本程序采用AVR Studio 4编写;主机程序:#include <avr/io.h>#define DD_SS 4 //SS引脚#define DD_MOSI 5 //MOSI引脚#define DD_SCK 7 //SCK引脚void SPI_MasterInit( ) //主机初始化{DDRB=(1<<DD_SS)|(1<<DD_MOSI)|(1<<DD_SCK); //设置SS、MOSI、SCK引//脚为输出SPCR=(1<<SPE)|(1<<SPR0)|(1<<MSTR); //使能SPI、频率为fosc/16、设置为//主机}unsigned char SPI_MasterTransmit(char data) //数据发送{SPDR=data;while(!(SPSR&(1<<SPIF))); //等待发送完成return SPDR;}main(){unsigned char data;unsigned char i=0x99; //需要发送的数据。
自己任意修改SPI_MasterInit( );data=SPI_MasterTransmit(i);}从机程序:#include <avr/io.h>#define DD_MISO 6void SPI_SlaveInit(void) //从机初始化{DDRB=(1<<DD_MISO); //设置MISO为输出SPCR=(1<<SPE); //使能SPI}char SPI_SlaveReceive(void) //从机接收数据{while(!(SPSR&(1<<SPIF))); //等待接收完成return SPDR; //返回接收的数据}main(){DDRC=0xff; //设置PC口为输出SPI_SlaveInit();PORTC=SPI_SlaveReceive(); //点亮断码管}仿真结果:测试完成。
mega16使用spi接口读取AD7705mega16使用spi接口读取AD7705,两个通道轮流读取标签:mega16 spi接口 AD7705 2007-03-28 10:05 阅读(597)评论(3)编辑删除两个通道依次读取,注意写通讯寄存器的数值,#include#include#define uchar unsigned char#define uint unsigned int#define Add_key PINC#define CS_1 (PORTB|= (1<<4 ))#define CS_0 (PORTB&= ~(1<<4 ))#define LED_1 (PORTB|= (1<<0 ))#define LED_0 (PORTB&= ~(1<<0 ))#define LED1_1 (PORTB|= (1<<1 ))#define LED1_0 (PORTB&= ~(1<<1 ))#define DRDY (PINB& 0x08)#define ADDR (PINC& 0x01)#define SPE_1 (SPCR|= (1<<6 ))uint value,value1,value2;uchar ch_flag=0;//**********************短延时程序50us**************************//void delay50us(uint t){uint j;for(;t>0;t--)for(j=0;j<70;j++);}//**********************短延时程序5us**************************//void delay5us(uint t){uint j;for(;t>0;t--)for(j=0;j<7;j++);}//**********************长延时程序50ms**************************//void delay50ms(uint t){uint i;for(;t>0;t--)for(i=0;i<52642;i++);}//**************************端口初始化*************************//void IO_Init(void){DDRC=0x00;PORTC=0x00;DDRB=0b10110111; //PB3\PB6输入PORTB=0b11110111; //MISO输入加上拉电阻}void spi_init(void){SPCR = 0b01011111; //使能SPI,MSB先发送,主机,SCK空闲高,模式三,128分频SPSR = 0x00; //setup SPI,主机倍频//CS_0; //使能SPI器件}//******************SPI写寄存器函数8BIT*******************************//void WriteToReg_ADC(uchar byteword){CS_0; //使能SPI器件//SPE_1;SPDR=byteword; //发送数据while(!(SPSR & (1<CS_1; //禁止SPI器件// delay5us(10);}//******************SPI读函数8BIT*******************************//unsigned char Read_Byte_SPI(void){SPDR = 0xff; //发送数据,给AD7705提供脉冲while (!(SPSR &(1<return SPDR;}//******************SPI读数据寄存器函数16BIT****************************//uint Read_ADC16BitValue(void){uchar temp1=0;uint temp=0;CS_0; //使能SPI器件temp=Read_Byte_SPI();temp=temp<<8;temp1=Read_Byte_SPI();temp=temp|temp1;CS_1; //禁止SPI器件return temp;}//******************绿灯闪烁******************************// void greenled(void){LED_0;delay50us(50);LED_1;delay50us(50);LED_0;delay50us(50);LED_1;delay50us(50);}//******************绿灯闪烁******************************// void yellowled(void){LED1_0;delay50us(50);LED1_1;delay50us(50);LED1_0;delay50us(50);LED1_1;delay50us(50);}//**************************AD初始化*************************//void ADC_Init(void){uchar i;for(i=10;i>0;i--){WriteT oReg_ADC(0xff);} //持续DIN高电平写操作,恢复AD7705接口WriteToReg_ADC(0x20); //通道1,下一个写时钟寄存器WriteToReg_ADC(0x0a); //写时钟寄存器设置更新速率为200hz WriteToReg_ADC(0x10); //通道1,下一个写设置寄存器WriteToReg_ADC(0x40); //自校准,增益1,双极,缓冲delay50us(100); //延时WriteToReg_ADC(0x21); //通道2,下一个写时钟寄存器WriteToReg_ADC(0x0a); //写时钟寄存器设置更新速率为200hz WriteToReg_ADC(0x11); //通道2,下一个写设置寄存器WriteToReg_ADC(0x40); //自校准,增益1,双极,缓冲delay50us(100);}//***************************按照通道1读取****************************//void Read_ch1(void){uint temp1=0;{temp1=Read_ADC16BitValue();//读取LED_1; //进入AD,指示等灭yellowled(); //黄灯闪烁}greenled(); //绿灯闪烁value1=temp1;WriteToReg_ADC(0x39);// 下一操作为读数据寄存器2}//***************************按照通道2读取****************************//void Read_ch2(void){uint temp2=0;if(DRDY==0) //数据准备好{temp2=Read_ADC16BitValue();//读取LED_1; //进入AD,指示等灭yellowled(); //黄灯闪烁}greenled(); //绿灯闪烁value2=temp2;WriteToReg_ADC(0x38); //下一操作为读数据寄存器1}//********************获取两个通道模拟量数值***************// void get_ad(void){{ch_flag++;if(ch_flag==0x03){ch_flag=0x00;}if(ch_flag==0x01){ Read_ch1();}if(ch_flag==0x02){ Read_ch2();}}}//***********************主程序*********************************//void main(void){delay50us(100); //延时等待外围器件稳定IO_Init();spi_init();ADC_Init();while(1){get_ad();greenled(); greenled(); greenled(); //绿灯闪烁}}。
/********************************************************************* MCU: ATmega16外部晶振:8MHz程序功能:4*4鍵盤識別,LED七段數碼管顯示,密碼功能模塊,直流電機正反轉控制AD轉換模塊, 模擬比較器,外部中斷應用,12864液晶,C/T0硬件設計:參考PROTUES硬件仿真電路調試:所有程序主要功能都軟硬件仿真通過,實際使用時要根據需要加入可靠性。
編譯環境:ICC AVRDesign by: wdw********************************************************************/#include<iom16v.h>#include<macros.h>#include<math.h>#define uchar unsigned char#define uint unsigned int#define SET_1(a,b) a|=bit(b) //將寄存器a的第b位置1#define CLR_0(a,b) a&=~bit(b) //將寄存器a的第b位清0#program date code:const date[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,//共陽數據;0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};#program duan code:const duan[]={0x20,0x10,0x08,0x04,0x02,0x01}; //段選;char adchannel;int dispbuf[]={0,0,0,0,0,0,}; //顯示緩存;uchar securbuf[]={0,0,0,0,0,}; //5位密碼緩存;/********************************************************************名稱:ms延時子函數功能:延時指定的ms*********************************************************************/ void delayms(int ms){int i,j;for(i=ms;i>0;i--){for(j=1722;j>0;j--); //8M时改为1141;} //12M时为1722;}/*******************************************************************名稱:us延時子程序功能:延時指定的us********************************************************************/ void delayus(uchar us){for(us;us<0;us--);{} //12M时单位T为1.45US}/********************************************************************单参数LED 显示硬件连接:数据PORTC-----D7~D0段选PORTD-----D7~D4*********************************************************************/ void LEDShow(long int shownum){uchar i,tmp,curnum;long int tmpnum;tmp = 0xfb;tmpnum = shownum;for(i=0;i<6;i++) //显示的位数为5{curnum = tmpnum % 10;tmpnum = tmpnum / 10;PORTD = tmp;PORTC = date[curnum];delayus(1);tmp = (tmp << 1) + 0x01; //补上移位造成的最右位为0;}}/*******************************************************名稱:七段LED共陽數碼管,在指定数位上显示指定的数,双参数功能:在指定的位置上顯示制定的數;硬件連接:PC口複用控制段選和位選,有2片573進行數據鎖存;*******************************************************/void show(uchar dat,uchar num) //六位七段數碼管顯示程序OK;{PORTC=date[dat];PORTD|=BIT(0);PORTD&=~BIT(0); //送數據;delayus(2);PORTC=0X00;delayus(1);PORTC=duan[num];PORTD|=BIT(1);delayus(2);PORTD&=~BIT(1);delayus(2);} //送選通信號;/************************************************************名稱:MCU端口初始化功能:設置MCU端口初始方向為輸出初始狀態為低*************************************************************/ void Gpioinit0(){DDRA=0XFF;PORTA=0X00;DDRB=0XFF;PORTB=0X00;DDRC=0XFF;PORTC=0X00;DDRD=0XFF;PORTD=0X00;}/***********************************************************名稱:MCU端口初始化功能:設置MCU端口初始為輸出初始狀態為高************************************************************/ void Gpioinit1(){DDRA=0Xff;PORTA=0XFF;DDRB=0xff;PORTB=0XFF;DDRC=0xff;PORTC=0XFF;DDRD=0xff;PORTD=0XFF;}/**************************************************名稱:單端口測試輸入:測試PC的任意端口號0~7功能:週期改變一個端口的電平**************************************************/void IOtest(uchar num){DDRC|=BIT(num);// while(1)// {PORTC|=BIT(num);delayms(50);PORTC&=~BIT(num);delayms(50);// }}/*************************************************名稱:按鍵動作檢測子程序。
A VR mega16 SPI 双机通讯程序代码
SPI
程序实现的功能:主机发送1~255,丛机接收并在LED上显示出来。
连接方式:两个mega16最小系统板PB4到PB7全部对连。
转自A VR与虚拟仪器
主机程序如下: // 功能:SPI主机模式,循环发送从1~255
#include <iom16v.h>
#include <macros.h>
void port_init(void)
{
PORTA = 0x00;
DDRA = 0x00;
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x00; //m103 output only
DDRC = 0x00;
PORTD = 0x00;
DDRD = 0x00;
}
//SPI initialize
// clock rate: 57599hz
void spi_init(void)
{
PORTB |= (1<<PB4) | (1<<PB5) | (1<<PB6) | (1<<PB7);
DDRB |= (1<<DDB5) | (1<<DDB7) | (1<<DDB4); //Set MOSI, SCK AND SS as outputs SPCR = 0x73; //setup SPI
SPSR = 0x00; //setup SPI
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
spi_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void SPI_MasterTransmit(char cData)
{
PORTB &=~ (1<<PB4); //强制接收方进入从模式
SPCR |= (1<<MSTR); // MSTR有时会被清零,这里强制进入主机模式/* 启动数据传输*/
SPDR = cData;
/* 等待传输结束*/
while(!(SPSR & (1<<SPIF)))
;
PORTB |= (1<<PB4);
}
void Delay(void) //延时,没有详细计算
{
unsigned int i,j;
for(i=1000;i>0;i--)
{
for(j=200;j>0;j--)
;
}
}
void main(void)
{
unsigned char i=0;
init_devices();
while(1)
{
for(i=255;i>0;i--)
{
SPI_MasterTransmit(i);
Delay();
}
}
}
复制代码从机程序如下: // 功能:从机模式,中断方式接收,并在LED上显示
#include <iom16v.h>
#include <macros.h>
void port_init(void)
{
PORTA = 0x00;
DDRA = 0xFF;
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x00; //m103 output only DDRC = 0x00;
PORTD = 0x00;
DDRD = 0x00;
}
//SPI initialize
// clock rate: 57599hz
void spi_init(void)
{
SPCR = 0xE3; //setup SPI
SPSR = 0x00; //setup SPI
}
#pragma interrupt_handler spi_stc_isr:11 void spi_stc_isr(void)
{
//byte in SPDR has been sent/received PORTA = SPDR;
}
//call this routine to initialize all peripherals void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
spi_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x00; //timer interrupt sources SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void main(void)
{
init_devices();
DDRB|=(1<<PB6); //MOSI 设置为输出while(1)
;//等待中断
}
复制代码
本文转自:新势力单片机[url][/url]。