头文件 "extern.h"
System_Clock EQU 8000000 // Used at UART, PS2, ...
//***********************IO定义
bit LED : PA.3 //定义LED灯的引脚
bit UART_Out: PA.5 //发送端口
//***********************串口配置
UART_Clock => 8000000; //UART时钟,选择1M、2M、4M、8M,其他值默认1M,若使用其他值请咨询FAE
FPPA_Duty => _SYS(INC.FPPA_NUM); // Single FPPA = 1, Mult FPPA = 2 or 4/8/...
Baud_Rate => 57600; //波特率
UART_Delay => ( (UART_Clock / FPPA_Duty) + (Baud_Rate/2) ) / Baud_Rate;
Test_MIN => UART_Clock / 1000 * 995;
Test_RUN => UART_Delay * Baud_Rate * FPPA_Duty;
Test_MAX => UART_Clock / 1000 * 1005;
#if (Test_RUN < Test_MIN) || (Test_RUN > Test_MAX)
.echo %Test_V0 <= %Test_RUN <= %Test_MAX
.error Baud_Rate do not match to System Clock
#endif
//************************变量定义
extern word adc_deal;
//************************函数定义
void LED_Init(void);
void ADC_init(void);
void ADC_data(void);
void UART_Send (void);
void UART_HandShake (void);
word Byte_Mul_Byte (byte a1,byte b1);
byte Byte_Div_Byte (word div_src,byte b1);
/* // A example for use ADCRH & ADCR
#if defined(ADCC)
#if defined(ADCR)
ADCRH EQU ADCR
ADCRL EQU 0
#else
ADCR EQU ADCRH
#endif
#endif
*/
main.c程序如下 :
本次仿真利用仿真器 没有考虑到功耗问题
正常市面上售卖的小夜灯熄灯功耗在100uA以下 需要略微调整频率
利用滞回特性做了一个中间过渡区间
#include "extern.h"
//************************变量定义
byte SYS_CLKMD;
void FPPA0 (void)
{
//系统时钟为高速时钟的8分频 供电电压为3.3v 高速时钟为16MHZ
.ADJUST_IC SYSCLK=IHRC/8, IHRC=16MHz, VDD=3.5V;
LED_Init();
ADC_init();
SYS_CLKMD = CLKMD; //初始记录系统时钟,在UART通讯后方便切回系统时钟
$ UART_Out High,Out;//设置UART的通讯脚(发送信号)
.delay 100; //等待
while (1)
{
ADC_data();
UART_HandShake();
if(adc_deal<90)
{
LED=1;
}
else if(adc_deal>120)
{
LED =0;
}
}
}
adc.c程序如下 :
此部分程序主要是采集光敏传感器ADC信号
#include "extern.h"
//==============ADC设置=========================
void ADC_init(void)
{
//注:选择的通道需设置为输入,无上拉、下拉电阻无数字输入;
PAC.4 = 0;
PAPH.4 = 0;
PADIER = 0b1110_1001;
$ ADCC Enable,PA4; //启用ADC功能,通道选择(AD转换的输入信号)
//启用:Enable;停用:Disable
//通道选择:PB1, PB2, PB3, PB4, PB5, PB6, PB7,PA3, PA4, PA0, BANDGAP
$ ADCM /4; //时钟源选择(系统时钟/X)
//X有/1, /2, /4, /8, /16, /32, /64, /128
//注:时钟源选择建议选用500K(/2)
$ ADCRGC VDD; //ADC参考高电压,可以选择VDD或外部引脚PB1
.delay 400; //延时400us
}
//************************变量定义
word adc_deal;
byte cds_adc_get_old;
void ADC_data(void)
{
//************************变量定义
byte cds_adc_get;
word adc_deal_old;
//**********************************开始ADC转换
AD_START = 1; //开始ADC转换
while(!AD_DONE) //等待ADC转换结果
NULL;
//当AD_DONE高电位时读取ADC结果
cds_adc_get = ADCR; //将ADC的值赋给data
//************************判断是否为误触发
#if 0
cds_adc_get_old=cds_adc_get;
adc_deal_old=Byte_Mul_Byte(cds_adc_get_old,20);
adc_deal=Byte_Mul_Byte(cds_adc_get,80);
adc_deal=adc_deal+adc_deal_old;
adc_deal=Byte_Div_Byte(adc_deal,100);
#else
adc_deal=cds_adc_get;
#endif
}
LED.c程序如下 :
驱动配置如下
#include "extern.h"
void LED_Init(void)
{
$ LED out,high; //初始把灯点亮(高电平点灯)
}
uart.c程序如下 :
串口频率设置为8Mhz 详见"extern.h"
波特率设置为57600 太高不太建议
输出为adc值
#include "extern.h"
//发送程序
void UART_Send (void)
{
BYTE cnt;
BYTE UART_Data_Out;
UART_Data_Out = A;
// Start Bit
set0 UART_Out; // 1
#if FPPA_Duty == 1
cnt = 8; // 2 ~ 3
.Delay 3; // 4 ~ 6
do
{ // Data Bit * 8
.Delay UART_Delay - 10;
sr UART_Data_Out; // 7
if (CF)
{
nop; // 10
UART_Out = 1; // 1
}
else
{
UART_Out = 0; // 1
.delay 2; // 2 ~ 3
}
} while (--cnt); // 4 ~ 6
.Delay UART_Delay - 5;
#else
.Delay UART_Delay - 4;
cnt = 8; // 2 ~ 3
// Data Bit * 8
do
{
sr UART_Data_Out; // 4 4
swapc UART_Out; // 1
.Delay UART_Delay - 4;
} while (--cnt); // 2, 3
.Delay 2; // 3 ~ 4
#endif
// Stop Bit
set1 UART_Out; // 1
.Delay 2 * UART_Delay - 2;
}
//***********************变量声明
extern byte SYS_CLKMD;
void UART_HandShake (void)
{
CLKMD = 0x34;//将系统时钟修改为设定的UART时钟
nop;//等待
//*********************发送回车加换行
A = adc_deal; //发送一个byte
UART_Send(); //发送数据
//*********************发送回车加换行
#if 0
A = 0X0a;
UART_Send(); //发送数据
A = 0X0d; //发送一个byte
UART_Send(); //发送数据
#endif
CLKMD = SYS_CLKMD; //数据发送结束后,切回原来的系统时钟
nop;//等待
}