AVR mega16 SPI 双机通讯 程序代码
ATMEGA16端口SPI扩展例子及源代码(HC595,驱动四位数码管)
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);}}}。
avr单片机SPI双机通信
MCUCSR = 0x80;//禁止JTAG
GICR = 0x00;
port_init();
spi_init();
sei();//开全局中断
}
//主函数
int main(void)
{
init_devices();
SPCR = 0xF1;
SPSR = 0x01;
}
SIGNAL(SIG_SPI) //一个字节发送或接收完成中断
{
PORTD=SPDR;
}
void spi_write(uchar sData)//功能:使用SPI发送一个字节
{
SPDR = sData;
{
DDRA=0XFF;
PORTA=spi_read();
}
//功能:使用SPI发送一个字节
void spi_write(uchar sData)
{
SPDR = sData;
while(!(SPSR & BIT(SPIF)));
//sData=SPDR;//读从机发回来的数据
}
//主函数
int main(void)
{
init_devices();
spi_write(0X09);
while(1)
{
NOP();
}
return 0;
}
从机:
//SPI双机通信 从机
//发送0x06,PA0~3接收
//SPI双机通信 主机
//发送0x09,接收方PD0~3,对应点小灯
//包含所需头文件
AVRmega16基本程序
/*********************************************************************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温度采集及通信程序
//基于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);}}}。
AVRmega16基本程序
枯藤老树昏鸦,小桥流水人家,古道西风瘦马。
夕阳西下,断肠人在天涯。
/*********************************************************************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);// }}/*************************************************名稱:按鍵動作檢測子程序。
AVR SPI两个单片机通信从机程序
voidinit(void);
voidtimer_init(void);
send_re(unsigned char num);
void delay_us(unsigned int num)
{unsigned int i,j;
/* * SPI_2.c * * Created: 2012-10-6 15:19:01 * Author: Administrator */
#include <avr/io.h>
#include <avr/signal.h>
#include<avr/interrupt.h>
unsigned char fnd[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
r=SPDR;//读取接受的数据。
return r;
}
void init(void)
{
//DDRB=(1<<PB2)|(1<<PB0)|(1<<PB1);
//SS=BIT0=0(输入),SCK=BIT1=1,MOSI=BIB=0X07;
SPCR=0X7F; //0111 1111,SPIF,SPE,DORD,MSTR, CPOL,CPHA,SPR1,SPR0
if (tr_count>9)
tr_count=0;
}
}
}
send_re(unsigned char num)
{
unsigned char r;
PORTB&=0XFE;//拉低/SS;
Atmega16的SPI双机通信例程
之前做双机通信的时候,可是把我给弄惨了,怎么做都不行,从机接到的数据一至是零。
在网上搜例程,然后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(); //点亮断码管}仿真结果:测试完成。
AVR单片机SPI通讯实例程序
else
{
SPI_RxHead++; //已接收数据计数器加1
}
}
else //如果spi_m为1,表明是发送状态
{
void spi_send(void)
{
if(spi_sending==0) //发送中标记为0,表明spi发送空闲
{
fill_tx_buffer(); //调用fill_tx_buffer函数,将要发送的数据加载到发送缓冲区
while(PINB.4==0) //如果PINB.4为低,表明总线被接受方占用,等待直至接受方发送完成。
{
SPI_RxHead = 0; //已接收数据还原
MSTR=1; //接收完成,将SPI设回主方式
spi_trans_com=1; //置接收完成标志
spi_sending=1; //置spi_sending标志表明发送进行中
SPDR=0xFF; //开始发送,接收方接收; //开SPI中断,
SPI_TxHead = 0; //已发送数据计数器清0
//******************************************
interrupt [SPI_STC] void spi_isr(void)
{
unsigned char data;
if(spi_m==0) //如果spi_m为0,表明是接收状态
{;}
InitSPI(); //初始化spi为主方式
DDRB.4=1;
SET_SPI_MODE=0; //将PORTB.4拉低,强迫接收方进入从接收方式
spi_m=1; //置spi_m标志表明为发送状态
mega16使用spi接口读取AD7705
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(); //绿灯闪烁}}。
AVRmega16基本程序
/********************************************************************* 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);// }}/*************************************************名稱:按鍵動作檢測子程序。
调试通过的AVR mega16 SPI双机通讯例子
//ICC-AVR application builder : 2007-7-18 13:01:11// Target : M16// Crystal: 7.3728Mhz// 作者:古欣// AVR与虚拟仪器[url][/url]// 功能: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 onlyDDRC = 0x00;PORTD = 0x00;DDRD = 0x00;}//SPI initialize// clock rate: 57599hzvoid 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 SPISPSR = 0x00; //setup SPI}//call this routine to initialize all peripheralsvoid init_devices(void){//stop errant interrupts until set upCLI(); //disable all interruptsport_init();spi_init();MCUCR = 0x00;GICR = 0x00;TIMSK = 0x00; //timer interrupt sourcesSEI(); //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();}}}//ICC-AVR application builder : 2007-7-18 12:56:10// Target : M16// Crystal: 7.3728Mhz// 作者:古欣// AVR与虚拟仪器[url][/url]// 功能:从机模式,中断方式接收,并在LED上显示#include <iom16v.h>#include <macros.h>void port_init(void){PORTA = 0x00;DDRA = 0xFF;PORTB = 0x00;DDRB = 0x00;PORTC = 0x00; //m103 output onlyDDRC = 0x00;PORTD = 0x00;DDRD = 0x00;}//SPI initialize// clock rate: 57599hzvoid spi_init(void){SPCR = 0xE3; //setup SPISPSR = 0x00; //setup SPI}#pragma interrupt_handler spi_stc_isr:11void spi_stc_isr(void){//byte in SPDR has been sent/receivedPORTA = SPDR;}//call this routine to initialize all peripheralsvoid init_devices(void){//stop errant interrupts until set upCLI(); //disable all interruptsport_init();spi_init();MCUCR = 0x00;GICR = 0x00;TIMSK = 0x00; //timer interrupt sourcesSEI(); //re-enable interrupts//all peripherals are now initialized}void main(void){init_devices();DDRB|=(1<<PB6); //MOSI 设置为输出while(1);//等待中断}。
ATMEGA16端口SPI扩展例子及源代码(HC595,驱动四位数码管)
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);}}}。
AVR单片机IO口模拟SPI四种模式的程序
时钟相位(CPHA)和时钟极性(CPOL)的不同组合使得SPI传输有了4种方式如果CPOL =0,SCK 引脚在空闲状态保持低电平;如果CPOL =1,SCK 引脚在空闲状态保持高电平时序图如下://IO端口定义#define SPI_SCK PC0#define SPI_MOSI PC1#define SPI_MISO PC2#define SPI_DDR DDRC#define SPI_PORT PROTC#define SPI_PIN PINC//端口操作符定义#define SCK_SET SPI_PORT|=_BV(SPI_SCK)#define SCK_CLR SPI_PORT&=~_BV(SPI-SCK)#define MOSI_SET SPI_PORT|=_BV(SPI_MOSI)#define MOSI_CLR SPI_PORT&=~_BV(SPI_MOSI)#define MISO_PIN PINC&_BV(SPI_MISO)#define DELAY_BUS //如需要延时,用延时函数替代此符号//模式1:CPOL=1 CPHA=1void spi_init(void){SCK_SET;SPI_DDR|=_BV(SPI_MOSI)|_BV(SPI_SCK);}uint8_t spi_readwrite_byte(uint8_t data){uint8_t i,ret=0;for(i=0;i<8;i++){//下降沿模拟if(data&0x80)//设置输出MOSI_SET;elseMOSI_CLR;SCK_CRL;//SCK产生下降沿DELAY_BUS;//上升沿模拟ret<<=1;if(MISO_PIN)//读数据ret|=1;SCK_SET; //SCK产生上升沿data<<=1;DELAY_BUS;}return ret;}//模式2:CPOL=0 CPHA=1void spi_init(void){SCK_CLR;SPI_DDR|=_BV(SPI_MOSI)|_BV(SPI_SCK);}uint8_t spi_readwrite_byte(uint8_t data) {uint8_t i,ret=0;for(i=0;i<8;i++){//上升沿模拟if(data&0x80)//设置输出MOSI_SET;elseMOSI_CLR;SCK_SET;//SCK产生上升沿DELAY_BUS;//下降沿模拟ret<<=1;if(MISO_PIN)//读数据ret|=1;SCK_CLR; //SCK产生下降沿data<<=1;DELAY_BUS;}return ret;}//模式3:CPOL=1 CPHA=0void spi_init(void){SCK_SET;SPI_DDR|=_BV(SPI_MOSI)|_BV(SPI_SCK);}uint8_t spi_readwrite_byte(uint8_t data) {uint8_t i,ret=0;//设置好输出口if(data&0x80)MOSI_SET;elseMOSI_CLR;for(i=0;i<8;i++){DELAY_BUS;//下降沿模拟ret<<=1;if(MISO_PIN)//读数据ret|=1;SCK_CRL;//SCK产生下降沿DELAY_BUS;//上升沿模拟data<<=1;if(data&0x80)//设置输出MOSI_SET;elseMOSI_CLR;SCK_SET; //SCK产生上升沿}return ret;}//模式4:CPOL=0 CPHA=0void spi_init(void){SCK_CLR;SPI_DDR|=_BV(SPI_MOSI)|_BV(SPI_SCK);}uint8_t spi_readwrite_byte(uint8_t data) {uint8_t i,ret=0;//设置好输出口if(data&0x80)MOSI_SET;elseMOSI_CLR;for(i=0;i<8;i++){DELAY_BUS;//上升沿模拟ret<<=1;if(MISO_PIN)//读数据ret|=1;SCK_SET;//SCK产生上升沿DELAY_BUS;//下降沿模拟data<<=1;if(data&0x80)//设置输出 MOSI_SET;elseMOSI_CLR;SCK_CLR; //SCK产生下降沿 }return ret;}。
AVR单片机之间的SPI通信
/******************ATmega16&SPI通信******************************** FileName:master.cAuthor:沧海麒麟Date:2011.05.26Version :1.0Description:单片机ATmega16之间的简单的SPI通信*/#include <iom16v.h> //常用头文件,如有需要可以查库文件include #include <avrdef.h>#include <macros.h>#include <string.h>#define uint unsigned int#define uchar unsigned char#define xtal 8char dat[] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};void Delay_1ms(void);void Delay_nms(uint n);void SPI_MasterPort_init(void);void SPI_MasterRegisters_init(void);void SPI_MasterTransmit(char cData);/*********************************************/void main(void){uchar i=0;SPI_MasterPort_init();SPI_MasterRegisters_init();while (1){for (i=0;i<8;i++){SPI_MasterTransmit(dat[i]);Delay_nms(500);}// end of if}// end of while}//****************************************void Delay_1ms(void){ uint i;for(i=1;i<(uint)(xtal*143-2);i++);}//============================================= void Delay_nms(uint n){uint i=0;while(i<n){Delay_1ms();i++;}}/*=====从机SPI引脚方向定义===============*/void SPI_MasterPort_init(void){PORTB |= 0x40; //SS(PB4自定义)MOSI(PB5自定义)DDRB |= 0xB0; //MISO(PB6输入)SCK(PB7自定义)}//============================================= void SPI_MasterRegisters_init(void){SPCR = (1 << SPE)|(1 << MSTR)|(1 << SPR0);}//============================================= void SPI_MasterTransmit(char cData){SPDR = cData;while (! (SPSR&(1 << SPIF)));}/******************ATmega16&SPI通信******************************** FileName:slave.cAuthor:沧海麒麟Date:2011.05.26Version :1.0Description:单片机ATmega16之间的简单的SPI通信*/#include <iom16v.h> //常用头文件,如有需要可以查库文件include#include <avrdef.h>#include <macros.h>#include <string.h>#define uint unsigned int#define uchar unsigned char#define xtal 8void Delay_1ms(void);void Delay_nms(uint n);void SPI_SlavePort_init(void);void SPI_SlaveRegisters_init(void);uchar SPI_SlaveReceive(void);//void SPI_SlaveTransmit(char cData);/*********************************************/void main(void){uchar temp;DDRA=0xFF;SPI_SlavePort_init();SPI_SlaveRegisters_init();while(1){temp = SPI_SlaveReceive();//接收一位数据SPSR &= ~BIT(SPIF);//PORTA = temp;temp = 0;}//end of while}//****************************************void Delay_1ms(void){ uint i;for(i=1;i<(uint)(xtal*143-2);i++);}//============================================= void Delay_nms(uint n){uint i=0;while(i<n){Delay_1ms();i++;}}/*=====从机SPI引脚方向定义===============*/void SPI_SlavePort_init(void){PORTB |= 0xF0; //SS(PB4输入)MOSI(PB5输入)DDRB |= 0x00; //MISO(PB6自定义)SCK(PB7输入)}//============================================= void SPI_SlaveRegisters_init(void){SPCR = (1 << SPE)|(1 << SPR0);}/*******************************/uchar SPI_SlaveReceive(void){while (!(SPSR&(1 << SPIF)));return SPDR;}/*void SPI_SlaveTransmit(char cData){SPDR = cData;while (! (SPSR&(1 << SPIF)));}*/。
AVR单片机ATmega16与计算机串行通信的实现
AVR单片机ATmega16与计算机串行通信的实现韦晓茹;蔡志坚;居戬之【期刊名称】《微型机与应用》【年(卷),期】2012(31)14【摘要】介绍AVR单片机ATmega16和计算机的串行通信的软、硬件设计,采用VisualBasic6.0中的MSComm通信控件实现计算机与单片机ATmega16之间的串行通信。
文章详细阐述了程序的设计流程,并给出了部分程序代码。
实验证明该系统可以实现ATmega16与计算机之间的通信。
%The hardware and software of serial EIA-232 communication between AVR single chip ATmegal6 and the computer are proposed. Communication control MSComm is used to realize the communication between the computer and the single chip. The flows of the program design are illustrated in details, and parts of program are also given. The experiment result indicates that the system works well.【总页数】4页(P30-33)【作者】韦晓茹;蔡志坚;居戬之【作者单位】苏州大学信息光学工程研究所,江苏苏州215006;苏州大学信息光学工程研究所,江苏苏州215006;苏州大学信息光学工程研究所,江苏苏州215006【正文语种】中文【中图分类】TN386.5【相关文献】1.Delphi环境下实现与AVR单片机的串行通信 [J], 李凯;左文香;夏国明;郭玉霞;张铁壁2.基于AVR单片机ATmega16的小型农用气象站设计 [J], 赵建周;韩庆妙3.PC机与AVR单片机之间串行通信的实现 [J], 丁易新4.PC机与AVR单片机之间串行通信的实现 [J], 姜文谦5.PC机与AVR单片机之间串行通信的实现 [J], 夏博锐因版权原因,仅展示原文概要,查看原文内容请购买。
基于mega16和M45PE16的SPI存储扩展与Proteus仿真
基于mega16和M45PE16的SPI存储扩展与Proteus仿真对mega16进行外部存储扩展,用M45PE16作为flash存储的扩展,两设备通过SPI接口进行通信。
用proteus进行仿真,结果如图:在SPI Debug-Monitor mode窗口我们看到这个程序执行的过程。
大概分为3部分:1,激活M45PE162,把数据写入M45PE163,从M45PE16中读出上步写入的数据源代码如下,M45PE16简称为M了:/*m45pe16.h 头文件,定义了一些常用的东西,在datasheet里都有。
前面一堆是对M进行操作的指令,后面的DL,driven low,把ss拉低。
DH,driven high,把ss拉高。
WAIT,等,等SPI口的传输完毕(每传一个byte就要加个WAIT)。
*/#ifndef M45PE16_H_#define M45PE16_H_#define WREN0X06#define WRDI0X04#define RDID0X9F#define RDSR0X05#define READ0X03#define FAST_READ0X0B#define PW0X0A#define PP0X02#define PE0XDB#define SE0XD8#define DP0XB9#define RDP0XAB#define DH PORTB|=(1<<4)#define DL PORTB&=~(1<<4)#define WAIT while(!(SPSR&(1<<SPIF)))#endif/* M45PE16_H_ *//*memoryspi.c 主程序文件。
具体的操作的含义注释里有。
*/#include<avr/io.h>#include<avr/interrupt.h>#include<avr/delay.h>#include "m45pe16.h"#define byte unsigned char#define word unsigned intbyte i;byte init_m45pe16(void){//上电后的初始化M,这个是必须的,在datasheet里有一句话,在开始任何操作之前要有一个falling edge。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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]。