@floatsd
2016-01-02T11:43:20.000000Z
字数 4817
阅读 1088
CM4实验报告
- 学习ADC模块原理和串口通信的原理
- 学习使用ADC模块转化外设传感器数据变为可调用的数字信息
- 将信息用UART输出
序列发生器 | 采样数 | FIFO深度 |
---|---|---|
SS3 | 1 | 1 |
SS2 | 2 | 4 |
SS1 | 3 | 4 |
SS0 | 8 | 8 |
SS处理采样控制和数据采集,所有序列发生器的实现方式相同,但采样数和FIFO深度不同。每个FIFO单元均为一个32位的字,低12位包含的是转换结果。
//配置PE3口为ADC单端采样模式,使用采样序列3采样内置温度感应器,处理器信号触发方式。
void main(){
int pui32ADC0Value;
//初始化系统时钟
g_ui32SysClock=SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ|SYSCTL_OSC_MAIN|SYSCTL_USE_PLL|SYSCTL_CFG_VCO_480),120000000);
//开启ADC0时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
//使能温度传感器PE3
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
//将PE3口配置成AD输入模式
GPIOPinTypeADC(GPIO_PORTE_BASE,GPIO_PIN_3);
//使用采样序列3来采样,ADC_TRIGGER_PROCESSOR为设定触发方式为控制器触发,由ADCProcessorTrigger()配合使用。
ADCSequenceConfigure(ADC0_BASE,3,ADC_TRIGGER_PROCESSOR,0);
//配置采样序列3的步骤0,配置模拟通道0(ADC_CTL_CH0)、采样结束产生中断(ADC_CTL_IE),转化结束后告诉ADC逻辑转化结束
ADCSequenceStepConfigure(ADC0_BSE,3,0,ADC_CTL_CH0|ADC_CTL_IE|ADC_CTL_END);
//使能采样序列3
ADCSequenceEnable(ADC0_BASE,3);
//开始采样前先清除采样序列3产生的中断
ADCIntClear(ADC0_BASE,3);
while(1){
//触发ADC0SS3。
ADCProcessorTrigger(ADC0_BASE,3);
//等待转换结束
while(!ADCIntStatus(ADC0_BASE,3,false)){}
//清除中断标志
ADCIntClear(ADC0_BASE,3);
//读取ADC0采样序列SS3的转化值,将结果存在pui32ADC0Value
ADCSequenceDataGet(ADC0_BASE,3,pui32ADC0Value);
//延时
SysCtlDelay(g_ui32Sysclock/12);
}
}
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h"
#include "driverlib/gpio.h"
#include "inc/hw_gpio.h"
#include "driverlib/adc.h"
UART(Universal Asynchronous Receiver/Transmitter), 异步串行通信接口,它可以实现数据的并串行转换,相对于同步模式,异步模式不需要一个专门的时钟信号来控制数据的收发,因此发送数据时位与位之间的间隙可以任意改变,但是并不是说不需要时钟信号,而是通过系统时钟或全局备用时钟产生一个可编程的波特时钟来控制发送数据。
- 接收处理器内部的并行数据,通过串行发送总线UnTX以异步通信的方式发送出去
- 输入接收总线UnRX上的串行数据,转换为并行数据后返回给处理器处理
- 数据接收或处理完后,经过T/R缓冲区FIFO,
标准的异步通信包括起始位,停止位,奇偶校验位。控制逻辑输出串行位流时,最先输出起始位,然后输出若干数据位(最低有效位在前),奇偶校验位和停止位。
接收逻辑单元在检测到有效的起始脉冲后,对接收到的串行位码流进行串-并转换,在接收过程中还要进行溢出错误检测、奇偶校验、帧错误检测、线终止检测、并将这些状态随数据一同写入接收FIFO中。
波特率分频系数是由16位整数部分和6位小数部分组成的22位二进制数,由此决定位时间,其中整数由UART波特率分频值整数(UARTIBRD)寄存器加载,小数通过UART波特率分频值小数(UARTFBRD)寄存器加载。波特率分频值(BRD)和系统时钟之间关系如下:
BRD=BRDI+BRDF=UARTSysClk/(ClkDiv*波特率)
式中UARTSysClk是连接到UART的系统时钟,ClkDiv是一个常数,取值为16或8(对应UARTCTL寄存器里第五位HSE=0/1,因此UART模块产生的内部波特率参考时钟频率总为波特率的8或16倍,分别称为)。默认情况下该系统时钟为‘时钟控制’中描述的主系统时钟,6位小数部分(寄存器[UARTFBRD]里[DIVFRAC]位域的值)计算方法如下:
UARTFBRD[DIVFRAC]=integer(BRDF*64+0.5)
即将波特率除数的小数部分乘64,加0.5以抵消舍入误差。需注意的是,梗概波特率除数之后,必须写一次(高字节)UARTLCRH寄存器,更改内容才会生效。
uart有8个模块,其中uart0是我们要用到的,它有调制解调器的功能(调制解调器流控制和调制解调器状态)//UART0使用PA0,PA1两个引脚,因此要使能GPIOA模块。
//UART0使用PA0,PA1两个引脚,首先使能GPIOA模块
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
//GPIO管脚复用,所以要对PA0,PA1两个引脚功能进行选择,这里将他们选择为执行UART0模块功能
GPIOPinConfigure(GPIO_PA0_U0RX);//PA0用于接收数据
GPIOPinConfigure(GPIO_PA1_U0TX);//PA1用于发送数据
//将PA0,PA1作为UART功能使用前进行配置
GPIOPinTypeUART(GPIO_PORTA_BASE,GPIO_PIN_0|GPIO_PIN_1);
UARTStdioConfig(0,115200,g_ui32SysClock);
//sysctl.h
//使能外设模块基址
void SysCtlPeripheralEnable(uint32_t ui32Peripheral);
//函数的定义和ui8Pins在gpio.h
//ui32PinConfig在pin_map.h,ui32Port在hw_mammap.h
//GPIOPinConfigure()一般和GPIOPinType...()一起使用来配置引脚。
void GPIOPinConfigure(uint32_t ui32PinConfig);
void GPIOPinTypeUART(uint32_t ui32Port, uint8_t ui8Pins);
/*******************************************************************
* 函数: ADC_Init()
* 描述: 初始化ADC0序列3和滚轮
* 输入值:无
* 返回值:无
*****************************************************************/
void ADC_Init()
{
// 初始化ADC0/PD7 AIN4 共20通道最大AIN19 分辨率为12bit 最大值4096
SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); //可选两个模块 ADC0和ADC1
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_7);
ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);
ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH4 | ADC_CTL_END | ADC_CTL_IE);
ADCSequenceEnable(ADC0_BASE, 3);
ADC0_HandlerFlag = false; //中断未发生
}
/*******************************************************************
* 函数: ADC_work()
* 描述: 数据采集,转化并用串口输出
* 输入值:无
* 返回值:无
*****************************************************************/
void ADC_work()
{
uint32_t ADC0_SS3v;
uint32_t ADC0_result;
ADCProcessorTrigger(ADC0_BASE, 3);
while(!ADCIntStatus(ADC0_BASE, 3, false)) ;
ADCSequenceDataGet(ADC0_BASE, 3, &ADC0_SS3v);
ADC0_result=(ADC0_SS3v * 3.3 *1000)/4096;
UARTprintf("V:%04d \n ", ADC0_result);
}