1.延迟函数的实现
我用的主频是72Mhz'
void delay_us(uint32_t us) {
// 这里假设你已经有了一个定时器或者使用了SysTick来实现精确的微秒级延时。
// 如果你使用的是SysTick,可以参考如下实现:
uint32_t ticks;
ticks = us * (72000000UL / 1000000UL);
ticks = us * 72;
uint32_t start = SysTick->VAL;
while ((SysTick->VAL - start) < ticks) {
__NOP(); // Do nothing until enough time has passed
}
}
2.adc0832.h
#ifndef ADC0832_H
#define ADC0832_H
#include "main.h" // 包含主文件中的定义,例如SPI_HandleTypeDef等
// 定义ADC0832相关的引脚
#define ADC_CS_PORT GPIOA // CS (Chip Select) Port
#define ADC_CS_PIN GPIO_PIN_4
#define ADC_CLK_PORT GPIOA // CLK (Clock) Port
#define ADC_CLK_PIN GPIO_PIN_5
#define ADC_DIN_PORT GPIOA // DIN (Data In) Port
#define ADC_DIN_PIN GPIO_PIN_6
#define ADC_DOUT_PORT GPIOA // DOUT (Data Out) Port
#define ADC_DOUT_PIN GPIO_PIN_7
// 函数原型声明
void ADC0832_GPIO_Init(void);
uint8_t ADC0832_ReadChannel(uint8_t channel);
#endif /* ADC0832_H */
3.adc0832.c
采用了软仿SPI最终传值0-256经过protues仿真证明没啥问题
void ADC0832_GPIO_Init(void) {
__HAL_RCC_GPIOA_CLK_ENABLE(); // 使能GPIOA时钟
GPIO_InitTypeDef GPIO_InitStruct = {0};
// 设置CS, CLK, DIN为输出模式
GPIO_InitStruct.Pin = ADC_CS_PIN | ADC_CLK_PIN | ADC_DIN_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(ADC_CS_PORT, &GPIO_InitStruct);
// 设置DOUT为输入模式
GPIO_InitStruct.Pin = ADC_DOUT_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(ADC_DOUT_PORT, &GPIO_InitStruct);
// 默认将CS设置为高电平,不选中ADC0832
HAL_GPIO_WritePin(ADC_CS_PORT, ADC_CS_PIN, GPIO_PIN_SET);
}
uint8_t ADC0832_ReadChannel(uint8_t channel) {
uint8_t command;
uint8_t temp=0;
uint8_t adc_value_h;
uint8_t adc_value_l;
uint16_t adc_value;
// 构建命令字节:Start Bit + Single/Differential + Channel Selection + MSBF
command = ((channel & 0x01) << 3) | 0x08 | 0x01;
// 选中ADC0832
HAL_GPIO_WritePin(ADC_CS_PORT, ADC_CS_PIN, GPIO_PIN_RESET);
delay_us(1); // 确保CS信号稳定
// 发送命令字节
for (int i = 0; i < 8; i++) {
HAL_GPIO_WritePin(ADC_CLK_PORT, ADC_CLK_PIN, GPIO_PIN_RESET); // 下降沿
if (command & 0x80) {
HAL_GPIO_WritePin(ADC_DIN_PORT, ADC_DIN_PIN, GPIO_PIN_SET);
} else {
HAL_GPIO_WritePin(ADC_DIN_PORT, ADC_DIN_PIN, GPIO_PIN_RESET);
}
command <<= 1;
delay_us(1); // 延迟确保信号稳定
HAL_GPIO_WritePin(ADC_CLK_PORT, ADC_CLK_PIN, GPIO_PIN_SET); // 上升沿
delay_us(1); // 延迟确保信号稳定
}
// 空闲时钟周期
HAL_GPIO_WritePin(ADC_CLK_PORT, ADC_CLK_PIN, GPIO_PIN_RESET);
delay_us(1); // 确保CLK信号稳定
HAL_GPIO_WritePin(ADC_CLK_PORT, ADC_CLK_PIN, GPIO_PIN_SET);
delay_us(1); // 确保CLK信号稳定
// 正方向接收
adc_value_h = 0;
for (int i = 0; i < 7; i++) {
if (HAL_GPIO_ReadPin(ADC_DOUT_PORT, ADC_DOUT_PIN)) {
adc_value_h |= 0x01;
}
adc_value_h <<= 1;
HAL_GPIO_WritePin(ADC_CLK_PORT, ADC_CLK_PIN, GPIO_PIN_SET);
delay_us(1); // 确保CLK信号稳定
HAL_GPIO_WritePin(ADC_CLK_PORT, ADC_CLK_PIN, GPIO_PIN_RESET);
delay_us(1); // 确保CLK信号稳定
}
if (HAL_GPIO_ReadPin(ADC_DOUT_PORT, ADC_DOUT_PIN)) {
adc_value_h |= 0x01;
}
if (HAL_GPIO_ReadPin(ADC_DOUT_PORT, ADC_DOUT_PIN)) {
temp |= 0x01;
}
adc_value_l |=(temp<<7);
HAL_GPIO_WritePin(ADC_CLK_PORT, ADC_CLK_PIN, GPIO_PIN_SET);
delay_us(1); // 确保CLK信号稳定
HAL_GPIO_WritePin(ADC_CLK_PORT, ADC_CLK_PIN, GPIO_PIN_RESET);
delay_us(1); // 确保CLK信号稳定
//反序接收
for (int i = 0; i < 7; i++) {
adc_value_l >>= 1;
if (HAL_GPIO_ReadPin(ADC_DOUT_PORT, ADC_DOUT_PIN)) {
temp |= 0x01;
}
adc_value_l |= (temp<<7);
HAL_GPIO_WritePin(ADC_CLK_PORT, ADC_CLK_PIN, GPIO_PIN_SET);
delay_us(1); // 确保CLK信号稳定
HAL_GPIO_WritePin(ADC_CLK_PORT, ADC_CLK_PIN, GPIO_PIN_RESET);
delay_us(1); // 确保CLK信号稳定
}
// 取消选中ADC0832
HAL_GPIO_WritePin(ADC_CS_PORT, ADC_CS_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(ADC_CLK_PORT, ADC_CLK_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(ADC_DOUT_PORT, ADC_DOUT_PIN, GPIO_PIN_SET);
delay_us(1); // 确保CS信号稳定
return adc_value_h;//理论上l和h是一样的但是实际仿真发现h更加精准
}