/*pic18->mcu_pic_18 avr->mcu_avr /*******************************/ #define _CPOL 0 //模式配置 #define _CPHA 0 //模式配置 /*******************************/ #ifdef mcu_51 #include "REG51.h" #define SCK_IO(x) (0?(P1&=0XFE):(P1|=0X01))//1->输出 0->输入 #define MOSI_IO(x) (0?(P1&=0XFD):(P1|=0X02)) #define MISO_IO(x) (0?(P1&=0XFB):(P1|=0X04)) #define SSEL_IO(x) (0?(P1&=0XF7):(P1|=0X08)) #define SCK_D(x) (x?(P1|=0X01):(P1&=0XFE)) #define MOSI_D(x) (x?(P1|=0X02):(P1&=0XFD)) #define SSEL_D(X) (X?(P1|=0X08):(P1&=0XF7)) #define MISO_I() (P1&0X04) #endif #ifdef mcu_pic_18 #include "PIC18.h" #define SCK_IO(x) (x?(TRISA&=0XFE):(TRISA|=0X01))//1->输出 0->输入 #define MOSI_IO(x) (x?(TRISA&=0XFD):(TRISA|=0X02)) #define MISO_IO(x) (x?(TRISA&=0XFB):(TRISA|=0X04)) #define SSEL_IO(x) (x?(TRISA&=0XF7):(TRISA|=0X08)) #define SCK_D(x) (x?(LATA|=0X01):(LATA&=0XFE)) #define MOSI_D(x) (x?(LATA|=0X02):(LATA&=0XFD)) #define SSEL_D(X) (X?(LATA|=0X08):(LATA&=0XF7)) #define MISO_I() (PORTA&0X04) #endif #ifdef mcu_avr #include "iom8535v.h" #define SCK_IO(x) (x?(DDRA|=0X01):(DDRA&=0XFE))//1->输出 0->输入 #define MOSI_IO(x) (x?(DDRA|=0X02):(DDRA&=0XFD)) #define MISO_IO(x) (x?(DDRA|=0X04):(DDRA&=0XFB)) #define SSEL_IO(x) (x?(DDRA|=0X08):(DDRA&=0XF7)) #define SCK_D(x) (x?(PORTA|=0X01):(PORTA&=0XFE)) #define MOSI_D(x) (x?(PORTA|=0X02):(PORTA&=0XFD)) #define SSEL_D(X) (X?(PORTA|=0X08):(PORTA&=0XF7)) #define MISO_I() (PINA&0X04) #endif extern void SPI_Init(void); extern unsigned char SPI_Send_Dat(unsigned char dat); extern void delay(unsigned char ms ); void delay(unsigned char ms ) { unsigned char m; while(ms--) for(m=0;m<100;m++); } /************************************************ 端口方向配置 与输出初始化 ************************************************/ void SPI_Init(void) { SCK_IO(1) ; MOSI_IO(1) ; MISO_IO(0) ; SSEL_IO(1) ; SSEL_D(1); MOSI_D(1); #if _CPOL==0 SCK_D(0); #else SCK_D(1); #endif } /********************************************** 模式零 ***********************************************/ #if _CPOL==0&&_CPHA==0 //MODE 0 0 unsigned char SPI_Send_Dat(unsigned char dat) { //第一数据sck上升之前 其他下降沿 数据采样 上升沿 unsigned char n,rx_dat; for(n=0;n<8;n++) { SCK_D(0);//下降沿 if(dat&0x80)MOSI_D(1); else MOSI_D(0); dat<<=1; SCK_D(1); //上升沿 rx_dat<<=1; if(MISO_I())rx_dat|=0x01; else rx_dat&=0xfe; } SCK_D(0); return rx_dat; } #endif /********************************************** 模式二 ***********************************************/ #if _CPOL==1&&_CPHA==0 //MODE 1 0 unsigned char SPI_Send_Dat(unsigned char dat) { //第一数据sck下降沿之前 其他上升沿 数据采样 下降沿 unsigned char n,rx_dat; for(n=0;n<8;n++) { SCK_D(1); if(dat&0x80)MOSI_D(1); else MOSI_D(0); dat<<=1; SCK_D(0); rx_dat<<=1; if(MISO_I())rx_dat|=0x01; else rx_dat&=0xfe; } SCK_D(1); return rx_dat; } #endif /********************************************* 模式一 *********************************************/ #if _CPOL==0&&_CPHA==1 //MODE 0 1 unsigned char SPI_Send_Dat(unsigned char dat) { //第一数据sck上升 其他上升沿 数据采样 下降沿 unsigned char n,rx_dat; SCK_D(0); for(n=0;n<8;n++) { SCK_D(1); if(dat&0x80)MOSI_D(1); else MOSI_D(0); dat<<=1; SCK_D(0); rx_dat<<=1; if(MISO_I())rx_dat|=0x01; else rx_dat&=0xfe; } return rx_dat; } #endif /////////////////////////////////////////////////////// /////////////////////////////////////////////////////// #if _CPOL==1&&_CPHA==1 //MODE 1 1 unsigned char SPI_Send_Dat(unsigned char dat) { //第一数据下降沿 其他下降沿 数据采样 上升沿 unsigned char n,rx_dat; SCK_D(1); for(n=0;n<8;n++) { SCK_D(0); if(dat&0x80)MOSI_D(1); else MOSI_D(0); dat<<=1; SCK_D(1); rx_dat<<=1; if(MISO_I())rx_dat|=0x01; else rx_dat&=0xfe; } return rx_dat; } /************************************* *************************************/ /*int main(void) { //DDRB=0Xff; SPI_Init(); while(1) { SSEL_D(0); P2=SPI_Send_Dat(0xaa); SSEL_D(1); //delay(100); } return 0; } */
上一篇:51单片机电子时钟
下一篇:经典单片机C51多任务代码(改进版)
推荐阅读最新更新时间:2024-03-16 14:24