3.3. 实现ADC7608的操作函数定义启动转换和片选引脚操作宏:
// adc cs
#define LCD_CS_HIGH() HAL_GPIO_WritePin(GPIOF, GPIO_PIN_6,GPIO_PIN_SET)
#define LCD_CS_LOW() HAL_GPIO_WritePin(GPIOF, GPIO_PIN_6,GPIO_PIN_RESET)
// adc conv
#define LCD_CV_HIGH() HAL_GPIO_WritePin(GPIOF, GPIO_PIN_3,GPIO_PIN_SET)
#define LCD_CV_LOW() HAL_GPIO_WritePin(GPIOF, GPIO_PIN_3, GPIO_PIN_RESET)
实现启动转换函数:
/*******************************************************************************
* Function Name : adc_getdata
* Description : get 8 channel sample from adc
* Input : data: data buffer
* Output : None
* Return : None
*******************************************************************************/
void adc_startconv(void)
{
LCD_CV_LOW();
__asm("nop");
__asm("nop");
__asm("nop");
__asm("nop");
LCD_CV_HIGH();
__asm("nop");
__asm("nop");
__asm("nop");
__asm("nop");
__asm("nop");
__asm("nop");
__asm("nop");
__asm("nop");
}
这里加了好多的nop主要是为了延时一下。
实现***读取驱动:
/*******************************************************************************
* Function Name : adc_getdata
* Description : get 8 channel sample from adc
* Input : data: data buffer
* Output : None
* Return : None
*******************************************************************************/
void adc_getData(uint8_t *data)
{
LCD_CS_LOW();
HAL_SPI_Receive(&hspi5,data, 18, 100);
LCD_CS_HIGH();
}
3.4. 循环读取AD采样值 if(VU1SendFlag == SET)
{
count++;
if(count > 0x7ffff)
{
adc_startconv();
HAL_Delay(1);
adc_getData(exchange_data.buf);
count= 0;
exchange_data.check = 0;
exchange_data.length = 18;
exchange_data.code = 0x01;
//计算校验
for(i=0;i
{
exchange_data.check += exchange_data.buf;
}
filldata++;
memcpy(VirtUart1ChannelBuffTx,(void *)&exchange_data,sizeof(_EXCHANGE_DATA));
VIRT_UART_Transmit(&huart1,VirtUart1ChannelBuffTx, sizeof(_EXCHANGE_DATA));
}
}
4. 创建A7端应用程序A7端的应用程序比较简单,主要功能是初始化RPMsg的tty通道,创建一个接收线程,等待CM4端程序发送的采样值***,并处理采样值和显示。
void* adc_thread(void *arg)
{
int ret, rc;
int32_t wsize;
_EXCHANGE_DATA ex_dat;
struct termios tiorpmsg;
//打开RPMsg的tty通道1用来获取***
mFdRpmsgData= open("/dev/ttyRPMSG1", O_RDWR | O_NOCTTY);
if (mFdRpmsgData < 0)
{
printf("Error opening ttyRPMSG1, err=-%d
", errno);
return (errno * -1);
}
while (1)
{
wsize= read(mFdRpmsgData, &ex_dat, sizeof(ex_dat));
if(wsize > 0)
{
uint16_t aDST_Buffer[9];
for(i=0;i<9;i++)
{
aDST_Buffer= ex_dat.buf[i*2];
aDST_Buffer<<= 8;
aDST_Buffer|= ex_dat.buf[i*2+1];
}
uint32_t s_data[8];
s_data[0]=((aDST_Buffer[0])<<2)|((aDST_Buffer[1]>>14)&0x0003);
s_data[1]=((aDST_Buffer[1]&0x3fff)<<4)|((aDST_Buffer[2]>>12)&0x000f);
s_data[2]=((aDST_Buffer[2]&0x0fff)<<6)|((aDST_Buffer[3]>>10)&0x003f);
s_data[3]=((aDST_Buffer[3]&0x03ff)<<8)|((aDST_Buffer[4]>>8)&0x00ff);
s_data[4]=((aDST_Buffer[4]&0x00ff)<<10)|((aDST_Buffer[5]>>6)&0x03ff);
s_data[5]=((aDST_Buffer[5]&0x003f)<<12)|((aDST_Buffer[6]>>4)&0x0fff);
s_data[6]=((aDST_Buffer[6]&0x000f)<<14)|((aDST_Buffer[7]>>2)&0x3fff);
s_data[7]=((aDST_Buffer[7]&0x0003)<<16)|( aDST_Buffer[8]&0xffff);
for(i=0;i<8;i++)
{
float f = (float)s_data * 10 / 131071;
printf("channel_%d s= %04x v=%3.3f
",i,s_data,f);
}
}
close(mFdRpmsgData);
}
5. 程序运行后的实际效果
下图中,红色线连接的绿色板式ADC7608的采集板,连接到DK1上。
下图是启动后获取8通道ADC***和经过计算后的结果,我加入的是直流3.3v,实际显示***基本相当。
基于CM4的SPI接口测试已经完成。接下来会测试下在CM4上产生PWM信号。
`