安霸SPI 剖析
最近在搞單片機(jī)和A5S的SPI通信
1、A5S是跑的是ITRON的系統(tǒng)、有自己相關(guān)的SPI API函數(shù) 2、單片機(jī)這邊也是可以熟悉了,發(fā)送,接收什么的,我都可以自模擬出來(lái) 3、但是問(wèn)題是,A5S上面的API函數(shù)的工作是如何的,我一直沒(méi)怎么弄清楚 4、一般的SPI通信,不都是主機(jī)提供時(shí)鐘信號(hào)嗎?可是我用A5S發(fā)送數(shù)據(jù)的時(shí)候,用示波器量時(shí)鐘引腳,并沒(méi)有看到有方波 5、不知所解呀最后發(fā)現(xiàn),在CSDN上發(fā)帖子,發(fā)完之后總是不記得自己有發(fā)過(guò),而且不知道在哪里找回來(lái),最后面自己搜索出來(lái)了 http://bbs.csdn.net/topics/390437622?page=1#post-394425594
//================================================================================================================================== 今天在我的系統(tǒng)上驗(yàn)證了那幾個(gè)API函數(shù)、發(fā)關(guān)的時(shí)候我用示波器去查看,MOSI引腳,發(fā)現(xiàn)有輸出、這讓我感到非常的高興,然后再用示波器去測(cè)了一下SCL引腳,發(fā)現(xiàn)SCL引腳竟然是低電平,一點(diǎn)反應(yīng)都沒(méi)有,查了一下資料,有些資料上寫著,SPI發(fā)送的時(shí)候應(yīng)該會(huì)進(jìn)行如下幾個(gè)步驟、
1、首先初始化一些什么寄存器呀,設(shè)置是發(fā)送多少位什么的,還有設(shè)置是低位先發(fā)送還是高位先發(fā)送
2、然后把數(shù)據(jù)填寫到發(fā)送的buffer里面去
3、發(fā)送buffer里面的數(shù)據(jù)把數(shù)據(jù)一位一位的移到MOSI上面去、實(shí)際上就是一個(gè)移位寄存器的原理
4、發(fā)送完成
后面我再測(cè)了一下EN腳,發(fā)現(xiàn)EN腳一直都是高電平、不過(guò)這里可以理解,可以理解成高電平使能發(fā)送
還有,我用串口打印了一下發(fā)送的那個(gè)API函數(shù),返回的值是0,說(shuō)明是這個(gè)函數(shù)已經(jīng)成功執(zhí)行了。
如果是這樣的話,那我從機(jī)要如何接收呢?主機(jī)沒(méi)有發(fā)送時(shí)鐘信號(hào),沒(méi)有時(shí)鐘信號(hào)是如何發(fā)送的,然后從
機(jī)要如何搞,真的是太不可理解了
#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 //500000void rtc_mcu_spi_init(void) {printk("---------rtc_mcu_spi_init--------------\n");#if 0gpio_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);#endifspi2_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\n",reg[0],reg[1]);if(Flag==0){printk("a5sspi_write_success----------\n");}else{printk("a5sspi_write_fail-------------\n");} }
之前用示波器查看那四個(gè)引腳,老是有問(wèn)題,今天借了另一塊板子來(lái)試了一下才知道,原來(lái)是我的板子有問(wèn)題,現(xiàn)此對(duì)安霸公司說(shuō)聲抱歉,你們的系統(tǒng)還是可以用的 片選 線沒(méi)有波形,時(shí)鐘線的數(shù)據(jù)線有波形、后面我做了如下的修正,可以用示波器看到片選信號(hào)的波形了
#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 對(duì)應(yīng)的是SPI的第二個(gè)接口了,但是SPI的第二個(gè)接口只能接一個(gè)SPI從設(shè)備,所以把這里改為0,而不是1#define MCU_SPI_MODE SPI_MODE0 #define MCU_SPI_DFS 0x77 //0x8 //full-duplex #define MCU_SPI_BAUD_RATE 50000 //500000void rtc_mcu_spi_init(void) {printk("---------rtc_mcu_spi_init--------------\n");#if 0gpio_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\n",reg[0],reg[1]);if(Flag==0){printk("a5sspi_write_success----------\n");}else{printk("a5sspi_write_fail-------------\n");} }
從這圖里看出來(lái),黃色的線就是SPI的片選使能線,我從A5S發(fā)送的是write_read的函數(shù),這個(gè)函數(shù)的話是先寫,再讀的,所以寫和讀的中間有一個(gè)高電平的脈沖~ 我又來(lái)了,今天可惡的灰熊拿下了雷霆,不喜歡他是因?yàn)樗麄兲蕴吮A_,好了,不說(shuō)了,說(shuō)下正事 SPI的全雙工工作模式:這里指的是用一個(gè)時(shí)鐘可以完成發(fā)送和接收一起的工作,比如8個(gè)時(shí)鐘,可以同時(shí)進(jìn)行發(fā)送和接收,因?yàn)榘l(fā)送和接收的引腳是不一樣的,這里已經(jīng)進(jìn)行過(guò)驗(yàn)證 下面貼出我今天調(diào)試出的通信,先從A5S發(fā)命令到單片機(jī),然后單片機(jī)判斷收到的是不是正確的,再回發(fā)消息給A5S,代碼如下: 單片機(jī)部分: #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做從機(jī)的配置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;//循環(huán)用到的變量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;//接收數(shù)據(jù)變量 }}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 //500000void rtc_mcu_spi_init(void) {printk("---------rtc_mcu_spi_init--------------\n");#if 0gpio_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,\n",reg);if(Flag==0){printk("a5sspi_write_success----------\n");}else{printk("a5sspi_write_fail-------------\n");} }
//weiqifartc_mcu_spi_init();app_timer_register(TIMER_1HZ, rtc_mcu_spi_handler);printk("=======mcu_spi==========\n");
總結(jié)
- 上一篇: STM32项目(五)——智能回收箱
- 下一篇: Linux 使用xmodmap禁用键盘按