本帖最后由 reayfei 于 2011-12-6 22:47 编辑
使用心得—从零开始学Cortex-M3内核单片机(四)
实验3 基于EK-LM3S811实现内部温度检测
模数转换器(ADC) 外设用于将连续的模拟电压转换成离散的数字量。
该Stellaris ADC模块的转换分辨率为10位,并支持4个输入通道,以及一个内部温度传感器。 ADC模块含有一个可编程的序列发生器,它可在无需控制器干涉的情况下对多个模拟输入源进行采样。
内部温度传感器:
内部温度传感器提供了模拟温度读取操作和参考电压。输出终端SENSO的电压通过以下等式计算得到:
SENSO= 2.7 - ((T +55) / 75)
关于中断设置:
打开启动文件Startup.s文件,找到想要设置的中断然后命名,假如你想用SysTick中断,那么在Startup.s文件中找到
这一行,将IntDefaultHandler 更换为你想要命名的中断函数名SysTick_ISR,再另起一行声明你用的中断函数 extern SysTick_ISR,这样配置的中断就可以使用了。
设置ADC3的函数入口:
重新命名并且声明,
测试截图:
源程序:
#include<lm3sxxx.h>
#include<stdio.h>
#define uint
unsigned int
#define uchar unsigned char
#define ulong unsigned long
ulong Sysclk =12000000UL;
tBoolean flag = false;
void jtagWait(void); // 防止JTAG失效
void clockInit(void); // 系统时钟初始化
void uartinit(void);
void put(const char *x);
void wellcome(void );
void SysTickInit(void);
void adcinit(void);
void tmpDisplay(ulong ulValue);
ulong adcSample(void);
int main(void)
{
ulongulValue;
jtagWait();
clockInit();
uartinit();
adcinit();
SysTickInit();
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC| SYSCTL_PERIPH_GPIOB | SYSCTL_PERIPH_GPIOE | SYSCTL_PERIPH_GPIOD);
//
使能KEY所在的GPIO端口
GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE,GPIO_PIN_0| GPIO_PIN_1);
//
设置KEY所在管脚为输入
GPIOPinTypeGPIOOutput(GPIO_PORTE_BASE,GPIO_PIN_0| GPIO_PIN_1);
//
设置KEY所在管脚为输入
GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE,GPIO_PIN_0| GPIO_PIN_1);
//
设置KEY所在管脚为输入
GPIOPinTypeGPIOOutput(GPIO_PORTC_BASE,GPIO_PIN_5);
//
设置KEY所在管脚为输入
GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_0| GPIO_PIN_1,0x00);
GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_0 |GPIO_PIN_1,0x00);
GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_0| GPIO_PIN_1,0x00);
wellcome();
while(1)
{
SysCtlSleep( ); // 睡眠,减少耗电以降低温度
ulValue = adcSample( );// 唤醒后ADC温度采样
tmpDisplay(ulValue); // 通过UART显示芯片温度值
}
}
//
防止JTAG失效
void jtagWait(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); //使能KEY所在的GPIO端口
GPIOPinTypeGPIOInput(GPIO_PORTC_BASE,GPIO_PIN_4); //设置KEY所在管脚为输入
if(GPIOPinRead(GPIO_PORTC_BASE,GPIO_PIN_4) == 0x00);//若复位时按下KEY,则进入
{
while(1); //死循环,以等待JTAG连接
}
SysCtlPeripheralDisable(SYSCTL_PERIPH_GPIOC);//禁止KEY所在的GPIO端口
}
void clockInit(void)
{
SysCtlLDOSet(SYSCTL_LDO_2_75V);
SysCtlClockSet(SYSCTL_XTAL_6MHZ |SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL
|SYSCTL_OSC_MAIN ); // The crystal is 50MHz
Sysclk=SysCtlClockGet();
}
void uartinit(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
GPIOPinTypeUART(GPIO_PORTA_BASE,GPIO_PIN_0 |GPIO_PIN_1);
UARTConfigSet(UART0_BASE,115200,UART_CONFIG_WLEN_8| UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE);
UARTEnable(UART0_BASE);
}
void put(const char *x)
{
while(*x!='\0')
{
UARTCharPut(UART0_BASE,*(x++));
}
}
void wellcome()
{
put("hello,21ic!\r\n");
SysCtlDelay(Sysclk);
}
void adcinit(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC);//时钟使能
SysCtlADCSpeedSet(SYSCTL_ADCSPEED_125KSPS);// 设置ADC采样速率
ADCSequenceDisable(ADC_BASE, 3);// 配置前先禁止采样序列
ADCSequenceConfigure(ADC_BASE,3,ADC_TRIGGER_PROCESSOR,0);
//ADC0 触发一直有效,优先级0
ADCSequenceStepConfigure(ADC_BASE,3,0,ADC_CTL_TS|ADC_CTL_IE|ADC_CTL_END);
//ADC0 步进0,完成采样后,使能中断,通道0(ADC0)
ADCIntEnable(ADC_BASE,3);
//三个中断使能
IntEnable(INT_ADC3);
IntMasterEnable();
//采样使能
ADCSequenceEnable(ADC_BASE,3);
}
void SysTickInit(void)
{
SysTickPeriodSet(Sysclk);// 设置SysTick计数器的周期值
SysTickIntEnable();
// 使能SysTick中断
IntMasterEnable();
// 使能处理器中断
SysTickEnable();
// 使能SysTick计数器
}
void tmpDisplay(ulong ulValue)
{
ulongulTmp;
charcBuf[40];
ulTmp =151040UL - 225 * ulValue;
sprintf(cBuf,"%ld.", ulTmp / 1024);
put(cBuf);
sprintf(cBuf,"%ld", (ulTmp % 1024) / 102);
put(cBuf);
put("℃\r\n");
}
// ADC采样
ulong adcSample(void)
{
ulongulValue;
ADCProcessorTrigger(ADC_BASE,3); // 处理器触发采样序列
while(!flag);// 等待采样结束
flag =false;// 清除ADC采样结束标志
ADCSequenceDataGet(ADC_BASE,3, &ulValue); // 读取ADC转换结果
return(ulValue);
}
void ADC3_ISR(void)
{
ulongvalue;
value=ADCIntStatus(ADC_BASE,3,true);
ADCIntClear(ADC_BASE,3);
if(value!=0)
{
flag=true;
}
}
// SysTick计数器的中断服务函数
void SysTick_ISR(void)
{
// 仅用于唤醒CPU,而不需要做其他事情
} |