1. 初始有电压的pin: vb, c13(1.7v), R, 3.3, a15, b4, 5v(没有5v), 3.3v
2. gpio操作
GPIO_InitTypeDef GPIO_InitStructure; // 1 声明一个结构体
// 为A、B、C类端口设置时钟 rcc ahb periph clock cmd rcc ahb periph cpio a enable
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; // 3 定义即将设置的口号
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; // 4 gpio mode
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; // 5 速度 gpio speed
// GPIO_Init(GPIOC, &GPIO_InitStructure); // 6
GPIO_Init(GPIOA, &GPIO_InitStructure); // 6 gpio init gpioa gpio init structure
GPIO_WriteBit(GPIOB, GPIO_Pin_9,(BitAction)(1));
GPIO_WriteBit(GPIOA, GPIO_Pin_13,(BitAction)(0)); 2. adc, dac 操作 typedef unsigned long u32; typedef unsigned short u16; typedef unsigned char u8;
char vol[6] = {"0.000v"};
static u8 fac_us=0;//us延时倍乘数 static u16 fac_ms=0;//ms延时倍乘数,在ucos下,代表每个节拍的ms数
// SYSCLK: 系统时钟频率, SYSCLK: 32
void delay_init(u8 SYSCLK)
{
// 1<<2: 8, 系统时钟的八分频
SysTick->CTRL &= (1<<2); //SYSTICK使用外部时钟源, SysTick->CTRL = SysTick->CTRL & ((1<<2)),关键
// Systick的时钟源你选择的是外部时钟的8分之一
fac_us = SYSCLK / 8; //不论是否使用ucos,fac_us都需要使用
fac_ms = (u16)fac_us * 1000; //代表每个ms需要的systick时钟数
}
void delay_ms(u16 nms) { u32 temp;
// n毫秒需要的时钟数, LOAD: 重装载寄存器?
SysTick->LOAD = (u32)nms*fac_ms; // 时间加载(SysTick->LOAD为24bit)
SysTick->VAL = 0x00; // 清空计数器,递减计数器
// 初始化为1
SysTick->CTRL = 0x01; // 开始倒数, CTRL
// CTRL一直加,直到等于LOAD??
do
{
temp=SysTick->CTRL;
}
while((temp & 0x01) && !(temp & (1<<16)));//等待时间到达
SysTick->CTRL = 0x00; //关闭计数器
SysTick->VAL = 0X00; //清空计数器
}
// ch: 8, 获取adc的值
u16 Get_Adc(u8 ch)
{
// 设置指定ADC的规则组通道,一个序列,采样时间
// ch: 8,1:优先级,ADC_SampleTime_96Cycles:采样时间,96个时钟周期
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_96Cycles ); //ADC1,ADC通道,采样时间为239.5周期
// 使能指定的ADC1,使软件启动转换功能
// CR2: ADC control register 2
ADC_SoftwareStartConv(ADC1);
// 等待转换结束,转换结束后返回为高电平 1 时结束循环
// SR: 状态寄存器
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));
// 返回最近一次ADC1规则组的转换结果,最后通过 ADCx->DR 获取到 数字值
// DR: 模数转换器常规数据寄存器
return ADC_GetConversionValue(ADC1);
}
// ch: 8, times: 10 u16 Get_Adc_Average(u8 ch,u8 times) { u32 temp_val=0; u8 t;
for(t=0;t<times;t++)
{
temp_val += Get_Adc(ch);
delay_ms(5);
}
return temp_val/times;
}
void ADC1_Config() { // GPIO的结构体 GPIO_InitTypeDef GPIO_InitStructure;
// ADC的结构体
ADC_InitTypeDef ADC_InitStructure;
/*----------------- ADC1 configuration with DMA enabled --------------------*/
/* Enable the HSI oscillator */
RCC_HSICmd(ENABLE);
/* Enable GPIOB clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
/* Configure PB.12 (ADC Channel8) in analog mode */
// pb0, ADC_IN8, 常规8通道
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; // GPIO_Mode_AN: 模拟输入???
// GPIO_InitStructure.GPIO_PuPd是STM32芯片的GPIO引脚上拉或下拉电阻的配置
// NOPULL表示不使用上拉或下拉电阻
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Check that HSI oscillator(振荡器) is ready */
while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);
/* Enable ADC1 clock */
// ADC1 时钟, adc1配置
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
// 扫描,多adc,ENABLE, 一个adc, DISABLE
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
// ENABLE,即连续转换, DISABLE, 单次转换, 触发区别
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
// 选择外部触发模式,
// ADC_ExternalTrigConvEdge_None: 软件触发
// 需要调用库函数:ADC_SoftwareStartConvCmd(ADC1, ENABLE);
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConvEdge_None;
// 数据对其方式,一般右对齐
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
// Specifies the number of ADC conversions that will be done
// using the sequencer for regular channel group.
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel18 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_4Cycles);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Wait until the ADC1 is ready */
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADONS));
// 控制 ADC1 开始转换
ADC_SoftwareStartConv(ADC1);
}
void DAC1_Config() { // 初始化PA4,DAC_OUT1 GPIO_InitTypeDef GPIO_InitStructure; // 初始化DAC结构体 DAC_InitTypeDef DAC_InitStructure;
// 时钟设置
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
// GPIO_Mode_AN:模拟输入
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
// 没有上拉和下拉
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// Specifies the external trigger for the selected DAC channel.
// DAC_Trigger_None: 没有外部触发
DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;
// Specifies whether DAC channel noise waves or triangle waves
// are generated, or whether no wave is generated. // 问题:噪声波是什么,三角波是什么,为什么要产生波 DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; // 作用是什么? DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0; // 指定DAC通道输出缓冲区是启用还是禁用 DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable; DAC_Init(DAC_Channel_1, &DAC_InitStructure);
// 使能 DAC 通道1
DAC_Cmd(DAC_Channel_1, ENABLE);
}
void Dac1_Set_Vol(uint16_t temp) { // 设置 DAC 通道 1 的数据 DAC_SetChannel1Data(DAC_Align_12b_R, temp);//12位右对齐数据格式设置DAC值 }
int main() { // adc 的值 u16 adc_value = 0x0000;
// 32mhz
delay_init(32);
ADC1_Config();
DAC1_Config();
while(1)
{
// Dac1_Set_Vol(2000); // pa4 // // 读1次adc值 // adc_value = Get_Adc(8); // pb0 // // 转换成电压,单位为mv // adc_value = (adc_value*3.3/4095)*1000; // GPIO_InitTypeDef GPIO_InitStructure; // // RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE); // // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; // // GPIO_Init(GPIOC, &GPIO_InitStructure); // // GPIO_ResetBits(GPIOC, GPIO_Pin_13); // // delay_ms(1000); // // GPIO_SetBits(GPIOC, GPIO_Pin_13); // // delay_ms(1000); } }