博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
安霸SPI 剖析
阅读量:1983 次
发布时间:2019-04-27

本文共 6417 字,大约阅读时间需要 21 分钟。

最近在搞单片机和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    //500000void rtc_mcu_spi_init(void){	printk("---------rtc_mcu_spi_init--------------\n");	#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\n",reg[0],reg[1]);	if(Flag==0){		printk("a5sspi_write_success----------\n");	}else{		printk("a5sspi_write_fail-------------\n");	}}
之前用示波器查看那四个引脚,老是有问题,今天借了另一块板子来试了一下才知道,原来是我的板子有问题,现此对安霸公司说声抱歉,你们的系统还是可以用的
片选 线没有波形,时钟线的数据线有波形、后面我做了如下的修正,可以用示波器看到片选信号的波形了
#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    //500000void rtc_mcu_spi_init(void){	printk("---------rtc_mcu_spi_init--------------\n");	#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\n",reg[0],reg[1]);	if(Flag==0){		printk("a5sspi_write_success----------\n");	}else{		printk("a5sspi_write_fail-------------\n");	}}
 
从这图里看出来,黄色的线就是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    //500000void rtc_mcu_spi_init(void){	printk("---------rtc_mcu_spi_init--------------\n");	#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,\n",reg);	if(Flag==0){		printk("a5sspi_write_success----------\n");	}else{		printk("a5sspi_write_fail-------------\n");	}}
//weiqifa	rtc_mcu_spi_init();    app_timer_register(TIMER_1HZ, rtc_mcu_spi_handler);			printk("=======mcu_spi==========\n");
你可能感兴趣的文章
Tomcat控制台中文乱码解决办法
查看>>
修改Tomcat控制台标题
查看>>
如何将解压版的tomcat设置为windows 服务启动
查看>>
异常:Invalid character found in the request target. The valid characters are defined in RFC 3986
查看>>
修改tomcat默认的session时间
查看>>
Tomcat之Session名称修改-springboot
查看>>
被捞起的“海底数据中心”,故障率仅为陆地1/8,微软新型数据存储模式又有新进展...
查看>>
展望数据中心市场未来十年发展趋势
查看>>
Microsoft Azure云服务停机!系水泵未知原因关闭导致
查看>>
干货|等保测评与网络架构
查看>>
高压细水雾灭火技术在数据中心机房中的消防应用
查看>>
数据中心机房建设中的关键问题都有哪些?
查看>>
配电技术——配电线路系统电气设备详解
查看>>
UPS电源如何安装?如何配置计算?故障如何处理?
查看>>
数据中心继续蓬勃发展的5个原因
查看>>
推进大数据中心新能源应用 广东省六部门联合印发培育新能源战略性新兴产业集群行动计划(2021—2025年)...
查看>>
消防电气IP防护等级如何定义和解读
查看>>
模块化是数据中心设计的未来
查看>>
灾备知识总结:容灾与备份区别、灾备技术、容灾体系规划
查看>>
网络故障排除工具 | 快速定位网络故障
查看>>