📄 adc.c
字号:
#include "ADC.h"
#include <stdio.h>
#include <system.h>
#include <rs232.h>
double ADCresmV;
void main(void) {
SoftwareTimer_t *ptr2Timer = &softTimer[0];
unsigned int ADCresult;
initializeInterruptDataStructs(); // 设置软件定时器数据结构
installTimer( // 1秒软件定时器,利用主定时器Timer0匹配方式实现
ptr2Timer, // 当Timer0发生与寄存器MR0匹配时产生中断
ONE_SEC_TIMER, // 中断频率为100Hz
TICKS_PER_1_SEC,
ONE_SEC_TIMER_INSTALLED
);
/* 检测连接器命令文件是否将中断向量安装在0地址,若是则将MEMMAP设为1,使程序从FLASH运行 */
#pragma segment = "INTVEC"
if (( void * )0x00000000UL == __segment_begin( "INTVEC" )) {
MEMMAP = 1; // 正常FLASH模式
}
else {
MEMMAP = 2 ; // 用户RAM模式-将最低64字节地址空间映射到内部RAM底部,并将异常向量映射到此处
}
/* 配置Timer0, 发生与MR0值匹配时产生一次中断 */
T0IR=0xFF; // 复位匹配及捕获中断
T0TCR=0; // 禁止计数
T0TC=0; // 清0定时计数器
T0PR= 0; // 无预分频
T0PC=0; // 清0预分频定时计数器
T0MR0=PCLKFREQ/100; // 计数36864个脉冲,产生100Hz中断,周期 = 10ms
T0MCR |= (RESET | INT_ON_MATCH); // 匹配时复位定时计数器与中断
T0TCR &= ~2; // 清0 复位标志
T0TCR = 1; // 允许计数
/* 设置VIC,所有中断都分配给IRQ */
VICIntSelect = 0; // 分配所有 VIC 中断给 IRQ
VICIntEnClear = 0xFFFFFFFF; // 禁止所有中断
VICSoftIntClear = 0xFFFFFFFF; // 清0所有软件中断
VICProtection = 0; // 可通过用户或特权模式访问 VIC
VICVectAddr = 0; // 清0中断
VICDefVectAddr = 0; // 清0默认 ISR 地址
/* 配置UART1的 RX 和 TX 引脚 */
PINSEL0 = (1<<ENABLE_UART1_RX) | (1<< ENABLE_UART1_TX); // PINSEL0 = 0x50000
// 配置UART1,9600波特率, 8位数据, 1位停止位, 无校验
U1FCR = 1; // 无论是否使用,都允许FIFO
SetBit(U1LCR,DIVISOR_LATCH_SET_bit); // U1LCR = 0X80 -> 允许访问除数锁存位,以便设置波特率
U1LCR |= EIGHT_BIT_CHARS; // 8位数据
ClrBit(U1LCR,PARITY_ENABLE_bit); // 无校验
ClrBit(U1LCR,STOP_BIT_SELECT_bit); // 1位停止位
U1DLL = PCLKFREQ / (9600 * 16);
U1DLM = (PCLKFREQ / (9600 * 16)) >> 8;
ClrBit(U1LCR,DIVISOR_LATCH_SET_bit); // 禁止访问除数锁存位
/* 配置ADC0 */
AD0CR_bit.SEL = 8; // 只允许AD0.3
AD0CR_bit.CLKDIV = PCLKFREQ / 4500000;
AD0CR_bit.BURST = 1; // 连续转换模式
AD0CR_bit.CLKS = 0; // 11时钟/10位精度
AD0CR_bit.PDN = 1; // 上电
PINSEL1_bit.P0_30 = 1; // 配置电位器引脚输出
/* 配置 VIC 控制寄存器,分配 IRQ 中断 */
VICProtection = 0; // 以用户/保护方式访问 VIC
VICDefVectAddr = (unsigned int)&NonVectISR; // 安装默认中断地址
/* 设置 Timer0 匹配中断 */
VICIntSelect &= ~(1<<VIC_TIMER0); // Timer0 IRQ中断
VICVectAddr0 = (unsigned int)&MM_TIMER0_ISR; // 将中断安装到 VIC 地址 slot
VICVectCntl0 = 0x20 | VIC_TIMER0; // IRQ 类型, 允许TIMER0中断
VICIntEnable |= (1<<VIC_TIMER0); // 启动Timer0中断
__enable_interrupt(); // 允许所有中断
AD0CR_bit.START = 0x0001; // 立即启动第一次转换
/* 前台循环,用户可加入其他代码,如定时器或按键响应等 */
while(TRUE) {
if(softTimer[ONE_SEC_TIMER].us_Event == TIMER_EXPIRED){
installTimer( // 重装1秒定时值
ptr2Timer,
ONE_SEC_TIMER,
TICKS_PER_1_SEC,
ONE_SEC_TIMER_INSTALLED
);
/* 获取上次 A/D 转换值,同时启动下一次转换 */
while(AD0DR_bit.DONE == 0); // 等待转换结束
AD0DR_bit.CHN = 0; // 通道0数据
ADCresult = AD0DR_bit.VVDDA ; // 保存转换值
ADCresmV = (ADCresult>>2)*3000/256; // 10位分辨率, 3V最大输入
printf("potentiometer now reads %4.2f\n\r",ADCresmV);
AD0CR_bit.START = 0x0001; // 启动下一次转换
}
} // 前台循环结束
} // 主程序结束
void installTimer (
SoftwareTimer_t *ptr2Timer,
unsigned int us_offset,
unsigned int us_ticks,
unsigned int us_event
) {
(ptr2Timer+us_offset)->us_Ticks = us_ticks;
(ptr2Timer+us_offset)->us_Event = us_event;
}
void initializeInterruptDataStructs(void) {
unsigned int i;
for(i=0;i<MAX_SOFTWARE_TIMERS;i++) {
softTimer[i].us_Ticks = 0;
softTimer[i].us_Event = EVENT_UNDEFINED;
}
}
/* IRQ中断句柄 */
#pragma vector=0x18
__irq __arm void IRQ_ISR_Handler (void) {
void (*interrupt_function)();
unsigned int vector;
vector = VICVectAddr; // 获得中断向量
interrupt_function = (void(*)())vector;
(*interrupt_function)(); // 通过指针调用向量中断函数
VICVectAddr = 0; // 清0 VIC 中断
}
/* TIMER0 中断服务函数 */
void MM_TIMER0_ISR() {
unsigned int IntType;
unsigned int i;
for(i=0; i<MAX_SOFTWARE_TIMERS; i++)
if(softTimer[i].us_Ticks > 1) // 如果定时器为减计数
softTimer[i].us_Ticks--;
else
softTimer[i].us_Event = TIMER_EXPIRED; // us_Ticks == 1; 定时时间到
IntType = (T0IR & 0xFF); // 确认中断类型
T0IR = (IntType & 0xFF); // 清0定时器中断
}
/* 非向量中断 */
void NonVectISR(void) {
while(TRUE); // 用户程序不会运行到这里
}
void sendByte(char byte) {
while (!(U1LSR &0x20)); // 当U1THR包含有效数据时,置1 THRE 位
U1THR = byte;
}
int putchar(int c) {
while(U1LSR_bit.THRE == 0); // 等待发送就绪
U1THR = c; // 发送字符
return c;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -