SPI 驱动初始化其实是标准的这里我们要驱动的是TI 的 ADC 芯片 ADS124S08,代码如下
头文件GPIO 定义
//GPIOA
#define N_ADC_DRDY_PIN GPIO_PIN_0
#define N_ADC_CS_PIN GPIO_PIN_4
#define ADC_SCK_PIN GPIO_PIN_5
#define ADC_DOUT_PIN GPIO_PIN_6 //SPI0 INPUT PIN
#define ADC_DIN_PIN GPIO_PIN_7
#define COM_SPI_OUT_PINS GPIO_PIN_5|GPIO_PIN_7 //SPI0 OUTPUT PINS
#define N_ADC_DRDY_PORT GPIOA
#define N_ADC_CS_PORT GPIOA
#define ADC_SCK_PORT GPIOA
#define ADC_DOUT_PORT GPIOA
#define COM_SPI_OUT_PORT GPIOA //SPI0 OUTPUT PINS
#define ADC_DIN_PORT GPIOA
SPI 初始化函数大家写的都差不多,关键注意标黄的两个参数(我们调整过)。
void spi_configuration(void) {
spi_parameter_struct spi_init_struct;
rcu_periph_clock_enable(RCU_GPIOA); // 使能GPIOA时钟
rcu_periph_clock_enable(RCU_SPI0); // 使能SPI0时钟
// SPI0配置为Master模式,全双工,波特率设置为1MHz
spi_i2s_deinit(SPI0);
spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
spi_init_struct.device_mode = SPI_MASTER;
spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT;
spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_1EDGE;
// spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
spi_init_struct.nss = SPI_NSS_SOFT;
spi_init_struct.prescale = SPI_PSC_8; // 设置波特率分频系数为8,即1MHz
spi_init_struct.endian = SPI_ENDIAN_MSB;
// spi_init_struct.endian = SPI_ENDIAN_LSB;
spi_init(SPI0, &spi_init_struct);
// enable SPI0
spi_enable(SPI0);
}
黄色的两行是我们在调试中修改的。一个是上升沿还是下降沿数据打入的问题,另一个是大小端的问题。不要只看文档,最好调试的时候try下。具体方法不是上来就配置寄存器,读ADC值,而是把ADC(或是您使用的其他SPI设备)的寄存器的default 的值读出来。如果以上这两个参数设的不对,那么能读出来数值,但是和文档的default 值对不上,就是知道错了。不要一上来就想trigger 一个写配置,读ADC值。一定会绕弯路。
我们配置 ADS124S08 并读取21个寄存器的代码如下:
unsigned char confige_124s08(unsigned char adc_addr_offset , unsigned char channel)
{
printf_("\r\nADS124S08 Init ");
gpio_init(N_ADC_CS_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, N_ADC_CS_PIN); // ADC /CS PIN
gpio_init(COM_SPI_OUT_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, COM_SPI_OUT_PINS); // SCK/MOSI
gpio_init(ADC_DOUT_PORT, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, ADC_DOUT_PIN); // MISO
amz_gpio_set_value(N_ADC_CS_PORT, N_ADC_CS_PIN, 0); // 初始化为低电平,选中ADS124S08
spi_configuration() ;
SPI_SendByte(0x20) ; // 读 reg 的 command , 从寄存器 0x0 开始读
SPI_SendByte(20) ; //读 20+1个寄存器
uint8_t i;
for(i=0 ; i<=20 ; i++)
printf_("\r\n 0x%x read: 0x%x" , i,SPI_SendByte(DUMMY_BYTE)) ;
return 0;
}
通过以上print_打印的串口log 我们就能看到读出的寄存器的值,和ADS124S08的手册对比,我们调整了这两个参数最终读到了正确值。
ADS124S08 Init
0x0 read: 0x8
0x1 read: 0x80
0x2 read: 0x1
0x3 read: 0x0
0x4 read: 0x14
0x5 read: 0x10
0x6 read: 0x0
0x7 read: 0xff
0x8 read: 0x0
0x9 read: 0x10
0xa read: 0x0
0xb read: 0x0
0xc read: 0x0
0xd read: 0x0
0xe read: 0x0
0xf read: 0x40
0x10 read: 0x0
0x11 read: 0x0
0x12 read: 0x0
0x13 read: 0x0
0x14 read: 0x0
这里我们再附上SPI 发送操作的代码,由于SPI是一个循环移位操作,DOUT发送完一个字节后(用 spi_i2s_data_transmit(SPI0,byte) 发送),DIN也能收回一个字节(用spi_i2s_data_receive(SPI0) 可以读出)。
uint8_t SPI_SendByte(uint8_t byte)
{
/* loop while data register in not emplty */
while (RESET == spi_i2s_flag_get(SPI0,SPI_FLAG_TBE));
/* send byte through the SPI0 peripheral */
spi_i2s_data_transmit(SPI0,byte);
/* wait to receive a byte */
while(RESET == spi_i2s_flag_get(SPI0,SPI_FLAG_RBNE));
/* return the byte read from the SPI bus */
return(spi_i2s_data_receive(SPI0)); // send a byte
}
以上是相对正规的范例代码。实际工程中,函数可以优化成根据实际SPI设备,可变字节数的读写。
————————————————
版权声明:本文为CSDN博主「小庐知行」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/tideyin123/article/details/151087181
|
|