|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区
您需要 登录 才可以下载或查看,没有账号?立即注册
×
使用MCU自带的比较器进行ADC转换, 并通过串口输出结果. 用定时器0产生10us中断查询比较器的状态.- #define MAIN_Fosc 22118400L //定义主时钟
- #define BaudRate1 9600ul //定义波特率
- #define ADC_SCALE 50000 //ADC满量程, 根据需要设置
- #include "STC15Fxxxx.H"
- /************* 本地常量声明 **************/
- //CMPCR1
- #define CMPEN 0x80 //1: 允许比较器, 0: 禁止,关闭比较器电源
- #define CMPIF 0x40 //比较器中断标志, 包括上升沿或下降沿中断, 软件清0
- #define PIE 0x20 //1: 比较结果由0变1, 产生上升沿中断
- #define NIE 0x10 //1: 比较结果由1变0, 产生下降沿中断
- #define PIS 0x08 //输入正极性选择, 0: 选择内部P5.5做正输入, 1: 由ADCIS[2:0]所选择的ADC输入端做正输入.
- #define NIS 0x04 //输入负极性选择, 0: 选择内部BandGap电压BGv做负输入, 1: 选择外部P5.4做输入.
- #define CMPOE 0x02 //1: 允许比较结果输出到P1.2, 0: 禁止.
- #define CMPRES 0x01 //比较结果, 1: CMP+电平高于CMP-, 0: CMP+电平低于CMP-, 只读
- //CMPCR2
- #define INVCMPO 0x80 //1: 比较器输出取反, 0: 不取反
- #define DISFLT 0x40 //1: 关闭0.1uF滤波, 0: 允许
- #define LCDTY 0x00 //0~63, 比较结果变化延时周期数
- #define TIM_16BitAutoReload 0
- #define TIM_16Bit 1
- #define TIM_8BitAutoReload 2
- #define TIM_16BitAutoReloadNoMask 3
- #define Pin0 0x01 //IO引脚 Px.0
- #define Pin1 0x02 //IO引脚 Px.1
- #define Pin2 0x04 //IO引脚 Px.2
- #define Pin3 0x08 //IO引脚 Px.3
- #define Pin4 0x10 //IO引脚 Px.4
- #define Pin5 0x20 //IO引脚 Px.5
- #define Pin6 0x40 //IO引脚 Px.6
- #define Pin7 0x80 //IO引脚 Px.7
- #define PinAll 0xFF //IO所有引脚
- /************* 本地变量声明 **************/
- //sbit P_ADC = P1^2; //P1.2 比较器转IO输出端
- sbit P_ADC = P1^4; //P1.2 比较器转IO输出端
- u16 adc; //ADC中间值, 用户层不可见
- u16 adc_duty; //ADC计数周期, 用户层不可见
- u16 adc_value; //ADC值, 用户层使用
- bit adc_ok; //ADC结束标志, 为1则adc_value的值可用. 此标志给用户层查询,并且清0
- /************* 本地函数声明 **************/
- void TxString(u8 *puts);
- void main(void)
- {
- u8 i;
- u8 tmp[5];
- //IO口初始化
- // P1n_push_pull(Pin2); //P1.2设置为push-pull output
- P1n_push_pull(Pin4); //P1.2设置为push-pull output
- P5n_pure_input(Pin4+Pin5); //P5.4 P5.5设置为高阻输入
- //比较器初始化
- CMPCR1 = 0;
- CMPCR2 = 20; //比较结果变化延时周期数, 0~63
- CMPCR1 |= CMPEN; //允许比较器 ENABLE,DISABLE
- // CMPCR1 |= PIE; //允许上升沿中断 ENABLE,DISABLE
- // CMPCR1 |= NIE; //允许下降沿中断 ENABLE,DISABLE
- // CMPCR1 |= PIS; //输入正极性选择, 0: 选择内部P5.5做正输入, 1: 由ADCIS[2:0]所选择的ADC输入端做正输入.
- CMPCR1 |= NIS; //输入负极性选择, 0: 选择内部BandGap电压BGv做负输入, 1: 选择外部P5.4做输入
- // CMPCR1 |= CMPOE; //允许比较结果输出到P1.2, ENABLE,DISABLE
- // CMPCR2 |= INVCMPO; //比较器输出取反, ENABLE,DISABLE
- CMPCR2 |= DISFLT; //内部0.1uF滤波, ENABLE,DISABLE
- //定时器0 初始化
- TMOD &= ~0x0f;
- Timer0_16bitAutoReload(); //设置为16位自动重装模式
- Timer0_1T(); //设置为1T模式
- ET0 = 1; //允许中断
- PT0 = 1; //高优先级中断
- TH0 = (u8)((65536 - MAIN_Fosc / 100000ul)>>8); //重装值 100KHZ, 10us, 65536 - (MAIN_Fosc)/100000
- TL0 = (u8)( 65536 - MAIN_Fosc / 100000ul);
- TR0 = 1; //开始运行
- //串口1初始化
- S1_USE_P30P31(); //UART1 使用P30 P31口 默认
- // S1_USE_P36P37(); //UART1 使用P36 P37口
- // S1_USE_P16P17(); //UART1 使用P16 P17口
- S1_8bit(); //8位数据,波特率可变
- S1_RX_Enable(); //允许接收
- S1_TXD_RXD_OPEN(); //将TXD与RXD连接中继断开 默认
- S1_BRT_UseTimer2(); //使用Timer2做波特率发生器
- ES = 0; //禁止中断, 使用查询发送
- Timer2_1T(); //Timer2 1T模式, 固定为16位自动重装
- T2L = (65536 - (MAIN_Fosc/4/BaudRate1)); //设置波特率重装值
- T2H = (65536 - (MAIN_Fosc/4/BaudRate1))>>8;
- Timer2_Run(); //允许定时器2计数
- EA = 1; //允许全局中断
- TxString("\r\n使用比较器做ADC例子\r\n"); //SUART1发送一个字符串
-
- while (1)
- {
- if(adc_ok) //等待ADC结束
- {
- adc_ok = 0; //清除ADC已结束标志
- TxString("ADC = "); //转十进制
- tmp[0] = adc_value / 10000 + '0';
- tmp[1] = adc_value % 10000 / 1000 + '0';
- tmp[2] = adc_value % 1000 / 100 + '0';
- tmp[3] = adc_value % 100 / 10 + '0';
- tmp[4] = adc_value % 10 + '0';
- for(i=0; i<4; i++) //消无效0
- {
- if(tmp[i] != '0') break;
- tmp[i] = ' ';
- }
- for(i=0; i<5; i++) //发串口
- {
- TI = 0;
- SBUF = tmp[i];
- while(!TI);
- TI = 0;
- }
- TxString("\r\n");
- }
- }
- }
- void TxString(u8 *puts) //发送一个字符串
- {
- for (; *puts != 0; puts++) //遇到停止符0结束
- {
- TI = 0;
- SBUF = *puts;
- while(!TI);
- TI = 0;
- }
- }
- /********************* Timer0中断函数************************/
- void timer0_int (void) interrupt TIMER0_VECTOR
- {
- if((CMPCR1 & CMPRES) == 0) P_ADC = 0; //比较器输出高电平
- else //P_ADC输出低电平, 给负输入端做反馈.
- {
- P_ADC = 1; //P_ADC输出高电平, 给负输入端做反馈.
- adc ++; //ADC计数+1
- }
- if(--adc_duty == 0) //ADC周期-1, 到0则ADC结束
- {
- adc_duty = ADC_SCALE; //周期计数赋初值
- adc_value = adc; //保存ADC值
- adc = 0; //清除ADC值
- adc_ok = 1; //标志ADC已结束
- }
- }
复制代码 |
|