DSP

安霸SPI 剖析

2019-07-13 20:10发布

最近在搞单片机和A5S的SPI通信

1、A5S是跑的是ITRON的系统、有自己相关的SPI API函数 2、单片机这边也是可以熟悉了,发送,接收什么的,我都可以自模拟出来 3、但是问题是,A5S上面的API函数的工作是如何的,我一直没怎么弄清楚 4、一般的SPI通信,不都是主机提供时钟信号吗?可是我用A5S发送数据的时候,用示波器量时钟引脚,并没有看到有方波 5、不知所解呀
最后发现,在CSDN上发帖子,发完之后总是不记得自己有发过,而且不知道在哪里找回来,最后面自己搜索出来了 http://bbs.csdn.net/topics/390437622?page=1#post-394425594
//================================================================================================================================== 今天在我的系统上验证了那几个API函数、发关的时候我用示波器去查看,MOSI引脚,发现有输出、这让我感到非常的高兴,然后再用示波器去测了一下SCL引脚,发现SCL引脚竟然是低电平,一点反应都没有,查了一下资料,有些资料上写着,SPI发送的时候应该会进行如下几个步骤、
1、首先初始化一些什么寄存器呀,设置是发送多少位什么的,还有设置是低位先发送还是高位先发送
2、然后把数据填写到发送的buffer里面去
3、发送buffer里面的数据把数据一位一位的移到MOSI上面去、实际上就是一个移位寄存器的原理
4、发送完成

后面我再测了一下EN脚,发现EN脚一直都是高电平、不过这里可以理解,可以理解成高电平使能发送
还有,我用串口打印了一下发送的那个API函数,返回的值是0,说明是这个函数已经成功执行了。
如果是这样的话,那我从机要如何接收呢?主机没有发送时钟信号,没有时钟信号是如何发送的,然后从
机要如何搞,真的是太不可理解了


#define MCU_SPI_EN GPIO(91) #define MCU_SPI_MISO GPIO(90) #define MCU_SPI_MOSI GPIO(89) #define MCU_SPI_SCL GPIO(88) #define MCU_SPI_ID 1 #define MCU_SPI_MODE SPI_MODE3 #define MCU_SPI_DFS 0x8 //full-duplex #define MCU_SPI_BAUD_RATE 500000 //500000 void rtc_mcu_spi_init(void) { printk("---------rtc_mcu_spi_init-------------- "); #if 0 gpio_config(MCU_SPI_EN, GPIO_FUNC_SW_INPUT); gpio_config(MCU_SPI_MISO, GPIO_FUNC_SW_INPUT); gpio_config(MCU_SPI_MOSI, GPIO_FUNC_SW_OUTPUT); gpio_config(MCU_SPI_SCL, GPIO_FUNC_SW_INPUT); gpio_set(MCU_SPI_EN); gpio_clr(MCU_SPI_SCL); gpio_set(MCU_SPI_MISO); gpio_set(MCU_SPI_MOSI); #endif spi2_config(0, MCU_SPI_MODE, MCU_SPI_DFS, MCU_SPI_BAUD_RATE); //spi_config_ena_pin_polarity(SPI_MASTER2, 0, SPI_CS_POL_HIGH); } void rtc_mcu_spi_handler(int eid) { u16 reg[2]; u16 ID=0xAAAA; unsigned char Flag=0; //reg[0]=0xaa55; //reg[1]=0xaa55; //Flag=spi2_write(MCU_SPI_ID, reg, 2); Flag=spi2_write_read(MCU_SPI_ID, &ID, reg ,1, 2); printk("======reg[0]-reg[1]===========:%x, %x ",reg[0],reg[1]); if(Flag==0){ printk("a5sspi_write_success---------- "); }else{ printk("a5sspi_write_fail------------- "); } }
之前用示波器查看那四个引脚,老是有问题,今天借了另一块板子来试了一下才知道,原来是我的板子有问题,现此对安霸公司说声抱歉,你们的系统还是可以用的 片选 线没有波形,时钟线的数据线有波形、后面我做了如下的修正,可以用示波器看到片选信号的波形了
#define MCU_SPI_EN GPIO(91) #define MCU_SPI_MISO GPIO(90) #define MCU_SPI_MOSI GPIO(89) #define MCU_SPI_SCL GPIO(88) #define MCU_SPI_ID 0 //spi2_config 对应的是SPI的第二个接口了,但是SPI的第二个接口只能接一个SPI从设备,所以把这里改为0,而不是1 #define MCU_SPI_MODE SPI_MODE0 #define MCU_SPI_DFS 0x77 //0x8 //full-duplex #define MCU_SPI_BAUD_RATE 50000 //500000 void rtc_mcu_spi_init(void) { printk("---------rtc_mcu_spi_init-------------- "); #if 0 gpio_config(MCU_SPI_EN, GPIO_FUNC_SW_INPUT); gpio_config(MCU_SPI_MISO, GPIO_FUNC_SW_INPUT); gpio_config(MCU_SPI_MOSI, GPIO_FUNC_SW_OUTPUT); gpio_config(MCU_SPI_SCL, GPIO_FUNC_SW_INPUT); gpio_set(MCU_SPI_EN); gpio_clr(MCU_SPI_SCL); gpio_set(MCU_SPI_MISO); gpio_set(MCU_SPI_MOSI); #endif //gpio_config(MCU_SPI_EN, GPIO_FUNC_SW_OUTPUT); //gpio_set(MCU_SPI_EN); spi2_config(MCU_SPI_ID, MCU_SPI_MODE, MCU_SPI_DFS, MCU_SPI_BAUD_RATE); //spi_config_ena_pin_polarity(SPI_MASTER2, 1, 0); } void rtc_mcu_spi_handler(int eid) { u16 reg[2]; u16 ID=0x0AB1; unsigned char Flag=1; reg[0]=0xaa55; reg[1]=0xaa55; //gpio_clr(MCU_SPI_EN); //Flag=spi2_write(MCU_SPI_ID, reg, 2); Flag=spi2_write_read(MCU_SPI_ID, &ID, reg ,1, 2); //gpio_set(MCU_SPI_EN); printk("======reg[0]-reg[1]===========:%x, %x ",reg[0],reg[1]); if(Flag==0){ printk("a5sspi_write_success---------- "); }else{ printk("a5sspi_write_fail------------- "); } }

从这图里看出来,黄 {MOD}的线就是SPI的片选使能线,我从A5S发送的是write_read的函数,这个函数的话是先写,再读的,所以写和读的中间有一个高电平的脉冲~我又来了,今天可恶的灰熊拿下了雷霆,不喜欢他是因为他们淘汰了保罗,好了,不说了,说下正事SPI的全双工工作模式:这里指的是用一个时钟可以完成发送和接收一起的工作,比如8个时钟,可以同时进行发送和接收,因为发送和接收的引脚是不一样的,这里已经进行过验证下面贴出我今天调试出的通信,先从A5S发命令到单片机,然后单片机判断收到的是不是正确的,再回发消息给A5S,代码如下:单片机部分:#ifndef _SPI_ #define _SPI_ //-------------------------------------------------------------- #define Master_SDO_DAT _pa5 //DEFINE SDI PIN #define Master_SDO_DATC _pac5 //DEFINE SDI CONTROL BIT #define Master_SDI_DAT _pa6 //DEFINE SDI PIN #define Master_SDI_DATC _pac6 //DEFINE SDI CONTROL BIT #define Master_SCK _pa7 //DEFINE SDI PIN #define Master_SCKC _pac7 //DEFINE SDI CONTROL BIT #define Master_SPIEN _pb5 //??SPI????????? #define Master_SPIENC _pbc5 //EN????? //-------------------------------------------------------------- void SPI_INIT(void); void MCUSPI_WRITE(unsigned char senddat); unsigned char MCUSPI_READE(void); #endif

dat=MCUSPI_READE(); if(dat==0x7E){ MCUSPI_WRITE(0xa9); }else { MCUSPI_WRITE(dat); }

void SPI_INIT(void) { //MCU做从机的配置 Master_SPIENC=1; Master_SDO_DATC=0; Master_SDO_DAT=0; Master_SDI_DATC=1; Master_SCKC=1; } void MCUSPI_WRITE(unsigned char senddat) { unsigned char i; if(!Master_SPIEN){ for(i=0;i<8;i++){ Master_SDO_DAT = senddat&0x80; while(Master_SCK); while(!Master_SCK); senddat <<= 1; } } } unsigned char MCUSPI_READE(void) { unsigned char R_Dat; unsigned char i;//循环用到的变量 Master_SDO_DAT=0; if(0==Master_SPIEN){ for(i=0;i<8;i++){ //if(0==i){ while(!Master_SCK); } R_Dat |= Master_SDI_DAT; if(i<7){ while(Master_SCK); while(!Master_SCK); } R_Dat <<= 1;//接收数据变量 } } return R_Dat; }

A5S部分: #define MCU_SPI_EN GPIO(91) #define MCU_SPI_MISO GPIO(90) #define MCU_SPI_MOSI GPIO(89) #define MCU_SPI_SCL GPIO(88) #define MCU_SPI_ID 0 #define MCU_SPI_MODE SPI_MODE0 #define MCU_SPI_DFS 0x77 //0x77//0x8 //full-duplex #define MCU_SPI_BAUD_RATE 50000 //500000 void rtc_mcu_spi_init(void) { printk("---------rtc_mcu_spi_init-------------- "); #if 0 gpio_config(MCU_SPI_EN, GPIO_FUNC_SW_INPUT); gpio_config(MCU_SPI_MISO, GPIO_FUNC_SW_INPUT); gpio_config(MCU_SPI_MOSI, GPIO_FUNC_SW_OUTPUT); gpio_config(MCU_SPI_SCL, GPIO_FUNC_SW_INPUT); gpio_set(MCU_SPI_EN); gpio_clr(MCU_SPI_SCL); gpio_set(MCU_SPI_MISO); gpio_set(MCU_SPI_MOSI); #endif //gpio_config(MCU_SPI_EN, GPIO_FUNC_SW_OUTPUT); //gpio_set(MCU_SPI_EN); spi2_config(MCU_SPI_ID, MCU_SPI_MODE, MCU_SPI_DFS, MCU_SPI_BAUD_RATE); //spi_config_ena_pin_polarity(SPI_MASTER2, 1, 0); } void rtc_mcu_spi_handler(int eid) { u8 reg; u8 ID=0x7E; unsigned char Flag=1; Flag=spi2_write_read(MCU_SPI_ID, &ID, ® ,1, 1); printk("======reg[0]-reg[1]===========:%x, ",reg); if(Flag==0){ printk("a5sspi_write_success---------- "); }else{ printk("a5sspi_write_fail------------- "); } }
//weiqifa rtc_mcu_spi_init(); app_timer_register(TIMER_1HZ, rtc_mcu_spi_handler); printk("=======mcu_spi========== ");