#include "HT46R02C.h"
/*
设置系统工作频率 4MHz
PWM 频率 31.25KHz??
上电复位前低电压宽 至少 1mS
复位后保持时间 至少 1mS
复位延时 至少 100mS
定时器0 时基
定时品1 LED快慢闪
PWM PWM
_delay( command ) ;系统内建的延时含数以指令周期为单位,4M RC下,一个指令周期1uS
1-263690 clocks //每个clocks 1微秒
*/
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
#define OFF 0 //LED状态
#define ON 1
#define SLOW 2
#define FAST 3
#define SLOW_VALUE 200 //该值越大,慢闪时越慢,反之越快
#define FAST_VALUE 20 //该值越大,快闪时越慢,反之越快
#define TMR0 _tmr0
#define TMR0C _tmr0c
#define TMR1 _tmr1
#define TMR1C _tmr1c
#define PA _pa
#define PAC _pac
#define PAPU _papu
#define PAWK _pawk
#define PB _pb
#define PBC _pbc
#define PBPU _pbpu
#define CTRL0 _ctrl0
#define CTRL1 _ctrl1
#define INTC0 _intc0
#define INTC1 _intc1
#define PWM0 _pwm0
#define ADRL _adrl
#define ADRH _adrh
#define ADCR _adcr
#define ACSR _acsr
uchar const testbit=0x01;
#define LED_Flash PA ^= (testbit<<1); //LED反向以闪烁 PA1
#define LED_On { LED_Mode=ON ; PA &=~(testbit<<1);} //LED常亮,LED负极接I/O口 PA1
#define LED_Off { LED_Mode=OFF ; PA |= (testbit<<1);} //LED常灭,LED负极接I/O口 PA1
#define PA6_Flash PA ^=(testbit<<6); //PA6脚取反
uchar LED_Mode;
uchar t_1s_flag;
uchar t_8ms_cnt;
uchar t_8ms_LED_cnt;
#define pwm_pin_hi_F PA |= 0b00000100 //改变此句中1的位置可改变PWM输出脚的位置
#define pwm_pin_low_F PA &= 0b11111011 //必变此句中1的位置可改变PWM输出脚的位置
uint PWM_CYCLE; //800 //此值变大,则PWM周期变长反之变短 100 40 200 20 400 10 800 5
//5HZ
uint pwm_counter;
uint pwm_duty;
//-----------------------------------------------系统初始化
void SysInit(void)
{
CTRL0 =0b00000010; //PFD由Timer1产生(本项目未用),PWM 7+1模式,PWM引脚I/O模式,引脚非PFD模式而是IO模式,slow startup,内部内部高速RC为时钟
CTRL1 =0b00111010; //禁止外部中断,时基选择2^13个系统时间中断一次,禁止看门狗
PA |= (testbit<<1); //PA1输出高电平,
PA &=~(testbit<<2); //PA2输出低电平,默认PWM无输出
PA |= (testbit<<5); //PA5输出高电平
PA &=~(testbit<<6); //PA6输出低电平
PAC &=~(testbit<<1); //
PAC &=~(testbit<<2);
PAC &=~(testbit<<5);
PAC &=~(testbit<<6); //PA1 PA2 PA5 PA6作为输出
TMR0C = 0x97; //定时器模式,Fsys作为时钟输入,计数使能,沿无关,128分频,4MHzRC频率下总线下,每定时器值每增加250个周期为8mS
TMR1C = 0x90; //定时器1使能模式,Fsys作为时钟输入,计数允许,沿无关,无分频
TMR0 = 6; //定时器0重装值赋初值,256-6=250
TMR1 = 0; //定时器1重装值赋初值, 256微秒一个中断 在百分之一的分辨率下,为40hz
//TMR1 = 256-0; //40hz
//TMR1 = 256-128; //80hz
//TMR1 = 256-64; //160hz
//TMR1 = 256-32; //320hz
//INTC0=0b00000101; //XXXX 中断标志全清零 ,定时器1中断禁止,定时器0中断使能,外部中断不使能,全局中断使能
INTC0 = 0b00001101; //XXXX 中断标志全清零 ,定时器1中断允许,定时器0中断使能,外部中断不使能,全局中断使能
INTC1=0b00000000; //AD中断不使能
ACSR=0b00000010; //AD时钟:sysClock/32; Tad=8uS>0.5uS
//ADCR=0b00000000; //使能PA0作为AD输入引脚,选择AN0引脚
ADCR=0b00001000; //使能PA0作为AD输入引脚,选择AN0引脚
}
/*-----------------------------------------------AD转换程序,12 位精度,无起泡
uint GetADC()
{
uchar i=0;
uint sample=0;
uint sum=0;
ADCR=0x08;
_delay(1000);
for(i=0;i<5;i++)
{
ADCR &=~(testbit<<7); //最高位写0
ADCR |= (testbit<<7); //设置PA0为AD通道,设置AN0为AD输入模式,选中AN0脚进行AD转换
ADCR &=~(testbit<<7); //最高位写1
//最高位写0 为开始
while( (ADCR & 0x40) !=0 )
;
sample= (uint)ADRH*16 + (uint)ADRL/16;
//result= (ADRH<<4) + (ADRL>>4);
sum += sample;
}
ADCR=0x00;
return sum/5; //5次求均值,进行滤波
}
//---------------------------------------带有泡泡的AD
int GetADC(void)
{
uint a[10]; //每次采集存入到这个数组
uint sum=0; //累加和
uint t=0; //临时变量,用于起泡法的两个元素交换
uchar i=0,j=0; //起泡法用的变量
ADCR=0x08;
for(i=0;i<10;i++) //采集十个数据
{
ADCR &=~(testbit<<7); //最高位写0
ADCR |= (testbit<<7); //设置PA0为AD通道,设置AN0为AD输入模式,选中AN0脚进行AD转换
ADCR &=~(testbit<<7); //最高位写1
//最高位写0 为开始
while( (ADCR & 0x40) !=0 );
a[i] = (uint)ADRH*16 + (uint)ADRL/16;
}
ADCR=0x00;
for(j=0;j<9;j++) //开始起泡法
{
for(i=0;i<9-j;i++)
{
if (a[i]>a[i+1])
{
t=a[i];
a[i]=a[i+1];
a[i+1]=t;
}
}
}
for(i=1;i<9;i++) //求出前面八个的和
sum+=a[i];
return(sum/8); //返回平均值
}
*/
//---------------------------------------带有去除峰值和起泡法的AD
int GetADC(void)
{
uint a[15]; //每次采集存入到这个数组 *
uint sum=0; //累加和
uint t=0; //临时变量,用于起泡法的两个元素交换
uchar i=0,j=0; //起泡法用的变量
ADCR=0x08;
for(i=0;i<15; ) //采集十五个数据 *
{
ADCR &=~(testbit<<7); //最高位写0
ADCR |= (testbit<<7); //设置PA0为AD通道,设置AN0为AD输入模式,选中AN0脚进行AD转换
ADCR &=~(testbit<<7); //最高位写1
//最高位写0 为开始
while( (ADCR & 0x40) !=0 );
a[i] = (uint)ADRH*16 + (uint)ADRL/16;
// if(a[i] <= 1393); // 如果值小于等于1.7V 才算数,计数加1*
// i++;
}
ADCR=0x00;
for(j=0;j<15;j++) //开始起泡法 *
{
for(i=0;i<15-j;i++)
{
if (a[i]>a[i+1])
{
t=a[i];
a[i]=a[i+1];
a[i+1]=t;
}
}
}
for(i=3;i<12;i++) //求出中间10个的值求平均 第0 1 2 不要,3-11保留,12 13 14不要 *
sum+=a[i];
return(sum/9); //返回剩余9个的平均值平均值
}
//------------------------------------------------定时器0中断 8mS定时
#pragma vector ISR_tmr0 @ 0x08
void ISR_tmr0(void)
{
//--------------------------------8mS定时中断
PA6_Flash;
t_8ms_cnt ++ ;
t_8ms_LED_cnt ++;
if(t_8ms_cnt>=125)
{
t_8ms_cnt =0;
t_1s_flag=1;
}
//-----------------LED闪烁处理
switch(LED_Mode)
{
case FAST:
if(t_8ms_LED_cnt >= FAST_VALUE) //快闪
{
t_8ms_LED_cnt=0;
LED_Flash;
}
break;
case SLOW:
if(t_8ms_LED_cnt >= SLOW_VALUE) //慢闪
{
t_8ms_LED_cnt=0;
LED_Flash;
}
break;
default:
t_8ms_LED_cnt =0 ; //其他模式直接清零,防溢出
break;
}
}
//------------------------------------------------定时器1中断 软PWM
#pragma vector ISR_tmr1 @ 0x0C
void ISR_tmr1(void)
{
pwm_counter ++;
if( pwm_counter >= PWM_CYCLE )
pwm_counter = 0; //处理周期问题
if( pwm_counter < pwm_duty )
pwm_pin_hi_F;
else
pwm_pin_low_F; //处理占宽问题
}
//--------------------------------------------------时基功能处理(指定一个中断函数,否则可能复位)
#pragma vector ISR_TBS @ 0x14
void ISR_TBS(void)
{
;
}
//-------------------------------------------------LED快闪三次
void LED_FlashFast3(void )
{
uchar i;
for(i=0;i<3;i++) //执行三次
{
LED_On;
_delay(150000); //亮150mS
LED_Off;
_delay(150000); //灭150mS
}
}
//----------------------------------------------主函数
void main(void )
{
uchar i=0; //循环体变量
uchar State=1; //全局状态标志,默认为1状态
uchar SampCnt2=0; //SEG2采样计数
uint SampCnt3=0; //SEG3采样计数
ulong SampCnt4=0; //SEG4采样计数
uchar CaptureFlag=0; //进入检测电压跌降模式标志
uint AD1=0; //AD转换结果
uint MaxAD1=0; //老的AD转换结果
PWM_CYCLE = 800;
pwm_counter = 0;
pwm_duty = 0;
LED_Off;
t_1s_flag=0;
t_8ms_cnt=0;
t_8ms_LED_cnt=0;
SysInit(); //系统初始化
LED_FlashFast3(); //LED快闪三次
LED_Off;
while(1)
{
LED_Mode = FAST;
pwm_duty = 100;