实验三 一、实验目的 (1) 了解模拟量采样的硬件电路;
(2) 熟悉 AD 的结构,掌握 AD 寄存器的使用方法;
(3) 掌握正确配置引脚的方法,实现指定功能;
(4) 熟悉串口的机制,掌握串口寄存器的使用方法;
(5) 实现模拟量采样,并将采样结果通过串口上传至 PC 端。 二、实验内容 (1) 运行AD 示例程序, 正确配置 PA0 引脚,实现 AD 采样功能;
(2) 运行 UART3 示例程序, 正确配置串口 3, 实现数据通过串口上传 PC;
(3) 按照实验要求编写应用程序。 三、实验中所用到的主要外设及其寄存器的简要说明 (1)ADC模数转换模块: 用来采集PA0口的电压值,并将其转换为数字量(0~4095)存放在ADC的DR寄存器中。 (2)DMA直接内存访问模块: 用来将ADC的DR寄存器中的值拷贝到内存中。 (3)四位数码管模块: 用来显示ADC采集到的电压值。接GPIOE.PIN[0:11]。其中GPIO.PIN[0:7]为段选端,分别对应某一位数码管的a-f, dp 段。DPIO.PIN[8:11]为位选端,分别对应从左至右第1-4位数码管。 (4)USART3串口模块: 用来将ADC采集到的电压值通过USART3发送给电脑。通过软件将电压值转换为四位字符数组,然后按字符放入USART3的DR寄存器中。等待硬件控制自动发送。等到USART3的SR寄存器的TC位置位后把下一位字符放入DR寄存器。直到四位字符全部发送完成。 (5)定时器TIM3: 用来为数码管计时,溢出周期是1ms。当计时器溢出时触发中断,点亮相应位的数码管,显示数字是步数的相应位。 (6)定时器TIM2: 用来为ADC采样计时,溢出周期时500ms。当计时器溢出时触发中断,开始一次ADC采样。 四、程序框图
五、核心程序 (1)main.c #include "stm32f10x.h" #include "adc.h" #include "dma.h" #include "nixie_tubes.h" #include "tim.h" #include "usart.h" #include "led.h" #include "stdio.h"
#define ADC_DATA_LEN 1
USART_Data data;
int main() { data.flag = 1;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); Adc1_Init(); Dma_Init((u32) &(ADC1->DR), (u32) &(data.dint), ADC_DATA_LEN); USART3_Init(115200); USART_NVIC_init(); Tim2_DelayMs_Init(500);
NixieTube_Init(); Tim3_Display_Init();
TIM_Cmd(TIM2, ENABLE); TIM_Cmd(TIM3, ENABLE);
while(1) { while(data.flag == 0); //Wait until data flag was set sprintf(data.dchar, "%4d", data.dint); //Transform the type of data from int into 4 characters Usart_send_datas(data.dchar); //Send data.dchar to USART3 data.flag = 0; //Reset data flag }
} (2)tim.c //定时器2中断服务程序 void TIM2_IRQHandler(void) //TIM2中断 { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //检查TIM2更新中断发生与否 { TIM_ClearITPendingBit(TIM2, TIM_IT_Update ); //清除TIMx更新中断标志 ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能 //MyDMA_Start_Once(); data.flag = 1; } }
//TIM3 for delay void TIM3_IRQHandler(void) { if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查TIM2更新中断发生与否 { TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); if(data_bit == 0) data_bit = 4;
switch(data_bit) { case 1: {Nixietube_light(1, data.dchar[0]);break;} case 2: {Nixietube_light(2, data.dchar[1]);break;} case 3: {Nixietube_light(3, data.dchar[2]);break;} case 4: {Nixietube_light(4, data.dchar[3]);break;}
default: break; }
data_bit -= 1; }
} (3)usart.c u8 Usart_send_datas(u8* data) { u16 k = 0;
for(k=0; *(data + k) != '\0'; k++) { USART_SendData(USART3,*(data + k)); while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET); } USART_SendData(USART3, 0x0d); while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET); USART_SendData(USART3, 0x0a); while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);
return 0;
} |