- /*---------------------------------------------------------------------------------------------
- Projest: 電壓邏輯筆
- Author: Wang Jiati [王家體]
- Note:
- 編譯器版本: HOLTEK C V3.31. 09/05/2014發布
- Product Name : ____________
- MCU Name : HT66F04
- File Name : D:\WANGJIATI\DESKTOP\邏輯筆\電壓邏輯筆\電壓邏輯筆.MTP
- HT-IDE Ver. : V7.85
- Compiler Ver. : HGASM 020
- Linker Ver. : V8.6
- CFG Ver. : V4.3
- ------------------------------------------------------------------------------------------------
- MTP File Checksum:[ DA00H ]
- Program Checksum:[ 76BEH ]
- Program+Option Checksum:[ 7771H ]
- Program+Option+Data Checksum:[ B731H ]
- ------------------------------------------------------------------------------------------------
- LVR Function Enable
- LVR Voltage Selection 2.55V
- High Speed/Low Speed System Oscillator Selection - fosc HIRC+LIRC
- fsub clock source LIRC
- HIRC frequency selection 8MHz @ Vdd=5V
- PTC clock source fptc LIRC
- XTAL OSC(1~24MHZ) build-in R enable enable
- WDT clock Selection -fs fsub
- Watchdog Timer Function Enable
- CLRWDT Instructions Selection 1 instruction
- PA7/RES Pin Options I/O pin
- ------------------------------------------------------------------------------------------------
- ------------------------------------------------------------------------------------------------*/
- /*--------------------------------------------------------------------------------------*/
- /*History 2014-9-22 V1.1
- ----------------------------------------------------------------------------------------*/
- #include "HT66F04.h"
- /*----------------------------------------------------------------------------------------
- 宏定義
- ----------------------------------------------------------------------------------------*/
- #define FREQ 8000000 //時鐘速度
- #define LED_9_PIN_H _pa6
- #define LED_9_PIN_CON _pac6
- #define LED_8_PIN_L _pa6
- #define LED_8_PIN_CON _pac6
- #define LED_7_PIN_H _pa5
- #define LED_7_PIN_CON _pac5
- #define LED_6_PIN_L _pa5
- #define LED_6_PIN_CON _pac5
- #define LED_5_PIN_H _pa4
- #define LED_5_PIN_CON _pac4
- #define LED_4_PIN_L _pa4
- #define LED_4_PIN_CON _pac4
- #define LED_3_PIN_H _pa3
- #define LED_3_PIN_CON _pac3
- #define LED_2_PIN_L _pa3
- #define LED_2_PIN_CON _pac3
- #define LED_1_PIN_H _pa1
- #define LED_1_PIN_CON _pac1
- #define Constant_PIN _pa2
- #define ADC_COUNTER 8 //中位值采樣次數.ADC緩沖去長度
- #define KEY_R_T0 40 //按鍵長按識別常熟
- #define EE_first 0x01 //第一次上電識別,初始化
- #define EE_vdd 0x08 //量程設置存儲位置
- #define EE_offset EE_vdd+1 //偏置存儲位置
- #define EE_Gain EE_offset+2 //增益系數存儲位置
- /* BIT/BYTE MANIPULATION ---*/
- #define FALSE 0
- #define TRUE 1
- #define MAKE8(var, offset) (((var >> (offset*8)) & 0xff)
- #define MAKE16(varhigh,varlow) (unsigned int)((varhigh&0xff)*0x100 + (varlow&0xff))
- #define WORD_LO(xxx) ((unsigned char) ((unsigned int)(xxx) & 255))
- #define WORD_HI(xxx) ((unsigned char) ((unsigned int)(xxx) >> 8))
- /*----------------------------------------------------------------------------------------
- 全局變量
- ----------------------------------------------------------------------------------------*/
- static volatile unsigned char work_mode; //工作模式
- static volatile unsigned char KeyTime; //記錄按鍵按下時長
- static volatile unsigned char power_time; //上電時長
- static volatile unsigned int cycle_h_now; //當前輸出頻率信號,高位
- static volatile unsigned int cycle_l; //設置頻率輸出信號
- static volatile unsigned int cycle_h;
- static volatile unsigned int vdd; //量程電壓, 5V*8192 =40960
- static volatile unsigned int adc; //
- static volatile float voltage; //采集來的電壓
- static unsigned int ADC_buffer[ADC_COUNTER]; //ADC緩沖
- static unsigned char vdd_step; //
- union {
- unsigned char data[2];
- volatile unsigned int O; //零點偏置
- } Offset;
- union {
- unsigned char data[3];
- volatile float G; //float 24bit
- } Gain; //增益系數
- typedef struct {
- unsigned int * volatile buffer; //緩沖區指針
- unsigned char counter; //隊列計數器
- } queue;
- volatile queue Queue_adc;
- typedef struct {
- unsigned char _LED1:1;
- unsigned char _LED2:1;
- unsigned char _LED3:1;
- unsigned char _LED4:1;
- unsigned char _LED5:1;
- unsigned char _LED6:1;
- unsigned char _LED7:1;
- unsigned char _LED8:1;
- unsigned char _LED9:1;
- unsigned char :6;
- unsigned char _flag:1;
- } _display_bits;
- union {
- _display_bits bits;
- volatile unsigned int data;
- } display_data;
- #define LED9 display_data.bits._LED9
- #define LED8 display_data.bits._LED8
- #define LED7 display_data.bits._LED7
- #define LED6 display_data.bits._LED6
- #define LED5 display_data.bits._LED5
- #define LED4 display_data.bits._LED4
- #define LED3 display_data.bits._LED3
- #define LED2 display_data.bits._LED2
- #define LED1 display_data.bits._LED1
- #define update_display_flag display_data.bits._flag
- typedef struct {
- unsigned char _State0:3;
- unsigned char _State1:3;
- unsigned char _key:1;
- unsigned char _disp:1;
- unsigned char _time:4;
- unsigned char _scan:1;
- unsigned char _pow:1;
- unsigned char _flag:1;
- unsigned char _out:1;
- } _step_bits;
- union {
- _step_bits bits;
- volatile unsigned int data;
- } step_data;
- #define display_flag step_data.bits._disp
- #define pwoer_flag step_data.bits._pow
- #define output_flag step_data.bits._out
- #define KeyState step_data.bits._State1
- #define KeySave step_data.bits._flag
- #define key_input step_data.bits._key
- #define ferq_step step_data.bits._State0
- #define update_time step_data.bits._time
- #define key_scan step_data.bits._scan
- const unsigned int vdd_date[6] = {20480,24576,27033,29491,36044,40960}; //5V*8192 =40960
- // 2.5, 3, 3.3, 3.6, 4.4, 5
- const unsigned int freq_date[5] = {31250,3125,1250,2500,1250};
- // 2, 20, 50, 100, 200};
- /*----------------------------------------------------------------------------------------
- 原型聲明
- ----------------------------------------------------------------------------------------*/
- unsigned int filter(unsigned char size, unsigned int buff[] );
- unsigned char queue_in(unsigned int* new_data, volatile queue* me);
- void setup_freq(unsigned char step);
- void DataEE_Read(unsigned char addr, unsigned char * _ram, unsigned char bytes);
- void DataEE_Write(unsigned char addr, unsigned char * _ram, unsigned char bytes);
- /*----------------------------------------------------------------------------------------
- Purpose: time_0 ISR
- ----------------------------------------------------------------------------------------*/
- DEFINE_ISR(MF_0F, 0x0C){ //頻率信號中斷服務
- if(_t0af == 1){
- _t0af = 0;
- if (output_flag ==1){
- output_flag = 0;
- Constant_PIN ^= 0x01;
- }
- if (cycle_h_now >0){
- cycle_h_now--;
- _tm0al =255;
- _tm0ah = 3;
- }else{
- output_flag = 1;
- cycle_h_now = cycle_h;
- _tm0al = WORD_LO(cycle_l);
- _tm0ah = WORD_HI(cycle_l);
- }
- }
- _mf0f = 0;
- }
- /*----------------------------------------------------------------------------------------
- Purpose: time_base_1 ISR
- ----------------------------------------------------------------------------------------*/
- DEFINE_ISR(time_base_1_ISR, 0x20){ //時基中斷TB1,每0.004096 秒中斷
- unsigned int temp;
- /*--讀ADC----*/
- _adoff = 0;
- _start = 0;
- _start = 1;
- _start = 0;
- while(_eocb == 1){
- GCC_CLRWDT();
- }
- temp = MAKE16(_adrh,_adrl);
- _adoff = 1;
-
- /*--存入ADC緩存,中位值濾波,折算電壓----*/
- if(queue_in( &temp, &Queue_adc) == 1 )
- {
- adc = filter( ADC_COUNTER, Queue_adc.buffer);
- if(adc > Offset.O){
- temp = adc - Offset.O;
- }else{
- temp = 0;
- }
- voltage = Gain.G * (float)(temp);
- }
- }
- /*----------------------------------------------------------------------------------------
- Purpose: time_base_0 ISR
- ----------------------------------------------------------------------------------------*/
- DEFINE_ISR(time_base_0_ISR, 0x1c){ //時基中斷TB0,每0.008192 秒中斷
- unsigned char temp;
- unsigned int temp_int;
- float temp_float2;
-
- //if(work_mode ==3){
- // _pac = 0xFA;
- //}else{
- _pac = 0xFB;
- //}
- if(display_flag == 1){ //屏服務
- display_flag = 0;
- if(LED9 == 1){
- LED_9_PIN_CON = 0;
- LED_9_PIN_H = 1;
- }
- if(LED7 == 1){
- LED_7_PIN_CON = 0;
- LED_7_PIN_H = 1;
- }
- if(LED5 == 1){
- LED_5_PIN_CON = 0;
- LED_5_PIN_H = 1;
- }
- if(LED3 == 1){
- LED_3_PIN_CON = 0;
- LED_3_PIN_H = 1;
- }
- if(LED1 == 1){
- LED_1_PIN_CON = 0;
- LED_1_PIN_H = 1;
- }
- }else{
- display_flag = 1;
- if(LED8 == 1){
- LED_8_PIN_CON = 0;
- LED_8_PIN_L = 0;
- }
- if(LED6 == 1){
- LED_6_PIN_CON = 0;
- LED_6_PIN_L = 0;
- }
- if(LED4 == 1){
- LED_4_PIN_CON = 0;
- LED_4_PIN_L = 0;
- }
- if(LED2 == 1){
- LED_2_PIN_CON = 0;
- LED_2_PIN_L = 0;
- }
- }
-
- if(++update_time == 6){ //6*8.192 = 49.152mS
- if(pwoer_flag == 1){ //上電計時,用于檢測上電按鍵
- if(++power_time >=43){
- pwoer_flag = 0;
- }
- }
- update_time = 0;
- key_scan = 1;
-
- /*--刷顯存----*/
- if(update_display_flag != 1){
- switch(work_mode){
- case 0:{ //電壓測量
- display_data.data &= 0XFE00;
- temp_int = 0x0001;
- for(temp=11; temp>=3; temp--){
-
- temp_float2 = ((float)(vdd)/8192)*((float)(temp)/10);
-
- if(voltage >= temp_float2){
- temp_int <<= (temp-3);
- display_data.data |= temp_int;
- break;
- }else{
- display_data.data |= 0;
- }
- }
- }break;
- case 1:{ //通斷
- display_data.data &=0xFE07;
- if(_cout ==1){
- display_data.data |= 0x01F0;
- }
- }break;
- case 2:{ //二極管
- display_data.data &=0xFE07;
- temp_int = 0x0008;
-
- for(temp=10; temp>=3; temp--){
- temp_float2 = (float)(temp)/10;
- if(temp==3){
- display_data.data |= 0x01F0;
- break;
- }
- else if(voltage >= temp_float2){
- temp_int <<= (temp-4);
- display_data.data |= temp_int;
- break;
- }else{
- display_data.data |= 0;
- }
- }
-
-
- }break;
- case 5:{ //校準偏置
- display_data.data &= 0XFE0A;
- if(adc > 40){
- LED9 = 1;
- }else if(adc > 20){
- LED8 = 1;
- }else if(adc > 10){
- LED7 = 1;
- }
- }break;
- case 6:{ //校準增益
- display_data.data &= 0XFE1A;
- if(adc > 3400){
- LED9 = 1;
- }else if(adc > 3000){
- LED8 = 1;
- }else if(adc > 2700){
- LED7 = 1;
- }
- }break;
- default: break;
- }
- }
- }
- }
- void DataEE_Read(unsigned char addr, unsigned char * _ram, unsigned char bytes) {
- unsigned char i;
-
- for (i = 0; i < bytes; i++, _ram++, addr++){
- _eea = addr; //讀地址
- _rden = 1; //讀使能
- _rd = 1; //開始讀
- //GCC_NOP();
- while(_rd){ //等待完成
- GCC_CLRWDT();
- }
- *_ram = _eed;
- _rden = 0; //清理
- }
- }
- void DataEE_Write(unsigned char addr, unsigned char * _ram, unsigned char bytes) {
- unsigned char i;
-
- for (i = 0; i < bytes; i++, _ram++, addr++){
- _eea = addr;
- _eed = *_ram;
- _wren = 1;
- _wr = 1;
- //GCC_NOP();
- while(_wr){
- GCC_CLRWDT();
- }
- _wren = 0;
- }
- }
- /*----------------------------------------------------------------------------------------
- Purpose: 頻率轉換 0.964HZ-250KHZ @ 8M時鐘
- ----------------------------------------------------------------------------------------*/
- void setup_freq(unsigned char step){
- unsigned int temp;
-
- if (step <= 2)
- {
- //temp = (FREQ/64/2) / freq_temp;
- _tm0c0 = 0b00111000; //fH/16
- }else{
- //temp = (FREQ/16/2) / freq_temp;
- _tm0c0 = 0b00101000; //fH/16
- }
- temp = freq_date[step];
- _tm0c1 = 0b11000001; //TM0比較器A匹配
- cycle_l = temp & 1023;
- cycle_h = temp >> 10;
- _tm0al =255;
- _tm0ah = 3;
- cycle_h_now = cycle_h;
- _t0on = 0;
- _t0on = 1;
- output_flag = 0;
- }
- /*----------------------------------------------------------------------------------------
- Purpose: 無符號int型數組 中位值濾波 排序采用選擇排序
- ----------------------------------------------------------------------------------------*/
- unsigned int filter(unsigned char size, unsigned int buff[] ){ //, unsigned char sensitive)
- unsigned int temp;
- unsigned char i,j,min;
-
- for( i=0;i<size;i++)
- {
- min=i;//先假設最小下標為i
-
- for(j=i+1;j<size;j++)
- if(buff[j]<buff[min]) //對i之后的數進行掃描將最小的數賦予min
- min=j;
- if(min!=i) //判斷min與i是否相等,若=則說明原假設正確反之交換數值
- {
- temp=buff[i];
- buff[i]= buff[min];
- buff[min]=temp;
- }
- }
-
- return buff[size/2];
-
- }
- /*----------------------------------------------------------------------------------------
- Purpose: 存入線性隊列
- ----------------------------------------------------------------------------------------*/
- unsigned char queue_in(unsigned int* new_data, volatile queue* me){
- me->buffer[me->counter] = *new_data;
- me->counter ++;
- if( me->counter >= ADC_COUNTER)//me->size)
- {
- me->counter = 0;
- return 1;
- }
- else
- {
- return 0;
- }
- }
- /*----------------------------------------------------------------------------------------
- Purpose: main
- ----------------------------------------------------------------------------------------*/
- void main(){
- unsigned char temp;
- unsigned int temp_int;
- //adc
- _adcr0 = 0b00010000;
- _adcr1 = 0b00000100;
- _acerl = 0b00000001;
- //TB
- _tbc = 0b11000110;
- _pac = 0xFB; //pa2 輸出模式
- _cpc = 0b00101001; //比較器設置
- _pac2 = 0;
- Constant_PIN = 1; //禁止恒流輸出
- Queue_adc.counter = 0;
- Queue_adc.buffer = ADC_buffer;
- DataEE_Read(EE_first, &temp, sizeof(temp));
- if(temp != 0xA5){ //第一次上電?
- vdd_step = 5;
- Offset.O = 0;
- Gain.G = 0.0016118633139910;
- temp = 0xA5;
- DataEE_Write(EE_first, &temp, sizeof(temp));
- DataEE_Write(EE_vdd, &vdd_step, sizeof(vdd_step));
- DataEE_Write(EE_offset, &Offset.data[0], sizeof(Offset.O));
- DataEE_Write(EE_Gain, &Gain.data[0], sizeof(Gain.G));
- }else{
- DataEE_Read(EE_vdd, &vdd_step, sizeof(vdd_step));
- DataEE_Read(EE_offset, &Offset.data[0], sizeof(Offset.O));
- DataEE_Read(EE_Gain, &Gain.data[0], sizeof(Gain.G));
- }
- vdd = vdd_date[vdd_step];
- pwoer_flag = 1;
-
- _wdtc = 0b11110000; //放狗,看門
- _tb1e = TRUE; //開TB1中斷,測量電壓
- _tb0e = TRUE; //開TB0中斷,顯示,按鍵,刷數
- _emi = TRUE;
-
- while(1){
- if(key_scan ==1){
- key_scan = 0;
- /*--按鍵掃描----*/
- temp = 0;
- key_input = _pa7; //讀取按鍵
- switch(KeyState){
- case 0:{
- if( key_input == 0 ){ //判斷是否有按鍵操作
- KeySave = key_input; //有,暫存當前按鍵
- KeyState =1;
- }
- }break;
- case 1:{
- if( key_input == KeySave ){ //按鍵抖動,
- KeyState = 2;
- KeyTime = KEY_R_T0 ; //第一次按鍵長按反應時間
- }else
- KeyState = 0;
- }break;
- case 2:{
- if( key_input == 0 ){
- if(--KeyTime <= 1 ){ //長按?
- temp = 2;
- KeyState = 3;
- }
- }else{
- temp =1;
- KeyState = 0;
- }
- }break;
- case 3:{
- if( key_input == 1 ){ //檢查按鍵彈起
- KeyState = 0;
- }
- }break;
-
- default: break;
- }
- if(temp !=0){
- update_display_flag = 1;
-
- /*--短按操作----*/
- if( temp ==1){
- if(work_mode ==3){
- ++ferq_step;
- if( ferq_step>4){
- _mf0e = FALSE;
- _mf0f = FALSE;
- _t0ae = FALSE; //禁止頻率輸出
- _t0af = FALSE;
- ferq_step = 0;
- work_mode = 0;
- Constant_PIN = 1;
- }
- }else if(work_mode ==4){
- ++vdd_step;
- if( vdd_step>5){
- vdd_step = 0;
- }
- }else if(work_mode ==7){
- work_mode = 0;
-
- DataEE_Write(EE_offset, &Offset.data[0], sizeof(Offset.O));
- DataEE_Write(EE_Gain, &Gain.data[0], sizeof(Gain.G));
-
- }else{
- ++work_mode;
- }
-
- }
- /*--長按操作----*/
- else if(temp ==2) {
-
- if(pwoer_flag == 1){
- work_mode = 5;
- pwoer_flag = 0;
- }else if(work_mode == 0){
- _tb1e = FALSE;
- work_mode = 4;
- }else if(work_mode == 4){
- vdd = vdd_date[vdd_step];
- work_mode = 0;
- DataEE_Write(EE_vdd, &vdd_step, sizeof(vdd_step));
- }
- }
- /*--更新工作模式----*/
- switch(work_mode){
- case 0:{ //電壓測量
- display_data.data = 0;
- _acerl = 1;
- Queue_adc.counter = 0;
- voltage = 0;
- _tb1f = FALSE;
- _tb1e = TRUE; //開TB0中斷
- }break;
- case 1:{ //通斷
- LED1 = 0;
- LED2 = 1;
- LED3 = 1;
- _tb1e = FALSE;
- _tb1f = FALSE;
-
- _cpc = 0b11101001;
- Constant_PIN = 0;
- }break;
- case 2:{ //二極管
- LED1 = 1;
- LED2 = 0;
- LED3 = 1;
-
- _cpc = 0b00101001; //比較器設置
- Constant_PIN = 0;
-
- _acerl = 1;
- Queue_adc.counter = 0;
- voltage = 0;
- _tb1f = FALSE;
- _tb1e = TRUE; //開TB0中斷
- }break;
-
- case 3:{ //頻率輸出(HZ)
- _tb1e = FALSE;
- _tb1f = FALSE;
- _acerl = 0;
- _pa0 = 0;
-
- display_data.data &= 0XFE00;
- LED1 = 1;
- LED2 = 1;
- LED3 = 1;
- temp_int = 0x0010;
- temp_int <<= ferq_step;
- display_data.data |= temp_int;
-
- setup_freq(ferq_step);
- _t0ae = TRUE;
- _mf0e = TRUE;
- }break;
- case 4:{ //設置量程
- display_data.data &= 0XFE00;
- LED1 = 1;
- LED2 = 1;
- LED3 = 0;
- temp_int = 0x0008;
- temp_int <<= vdd_step;
- display_data.data |= temp_int;
-
- }break;
- case 5:{ //校準偏置
- display_data.data &= 0XFE00;
- display_data.data |= 0x000A;
- }break;
-
- case 6:{ //校準增益
- Offset.O = adc;
- display_data.data &= 0XFE00;
- display_data.data |= 0x001A;
- }break;
-
- case 7:{ //保存校準
- Gain.G = (float)(5.0/(adc-Offset.O));
- display_data.data &= 0XFE00;
- display_data.data |= 0x003A;
- }break;
- default: break;
- }
- update_display_flag = 0;
- }else {
- update_display_flag = 0;
- }
- }
- GCC_CLRWDT(); //逗狗狗
- }
- }
- /*END-------------------------------------------------------------------------*/
復制代碼 |