📄 main.c
字号:
#include "math.h"
#include "a2000.h"
#include "hardware.h"
#include "LedTiSnd.h"
#define true 1
#define false 0
#define SND_DI_BASE 0 //嘀
#define SND_REP_BASE 1 //现在时刻
#define SND_HOUR 24 //点
#define SND_POINT 24 //点
#define SND_MIN 25 //分
#define SND_SEC 26 //秒
#define SND_NUM_BASE 6 //零(<=16)
#define SPK_TIME 10 //报时间隔一次(s)
#define SPK_VOLUME 1 //音量
#define MIN_SWITCH_TIME 512*2 //持续按下 2S 那么开启 V ADC 功能,关闭计时功能
#define MIN_REALSPK_TIME 128 //0.25S
#define MIN_VOLAGE_STBTIME 512 //1S
unsigned int g_spk_arr[32] = {0}; //播放列表
unsigned int g_spk_arr_idx = 0; //播放列表的长度
unsigned int g_spk_time_count = 0; //报时计数
unsigned char g_start_spk = false;
unsigned char g_led_index = 0; //当前显示的led序号
//从右至左(最右边为秒)
char g_led_sec_lo = 0;
char g_led_sec_hi = 0;
char g_led_min_lo = 0;
char g_led_min_hi = 0;
char g_old_sec_lo = 0;
char g_old_sec_hi = 0;
char g_old_min_lo = 0;
char g_old_min_hi = 0;
unsigned int g_base_2HZ_count = 0;
unsigned char g_vdc_enable = false; //当前是否处于电压测量状态
unsigned int g_vdc_start_timecount = false;
unsigned char g_vdc_set_parameter = false;
unsigned int g_volage_stbtime = 0; //稳定时间
unsigned char g_already_spk_volage = false; //是否已经自动报告了电压值
int g_switch_timecount = 0;
unsigned char g_start_realtime_spk = false; //如果为true将终止当前定点报时,开始按键报时
int main()
{
int i = 0;
unsigned long int uiData = 0;
unsigned int a,b,c,d;
__asm("int off");
//特设IOA4 带下拉电阻的输入,其他为带数据缓存器的高电平输出(无数据反相功能)
*P_IOA_Attrib = (0xffff&(~0x0010));
//*P_IOA_Dir = (0xffff&(~0x0010));
*P_IOA_Dir = (0xffff&(~0x0010))&(~0x0020); //IOA5悬浮输入,没有唤醒功能
*P_IOA_Data = (0xffff&(~0x0010));
*P_INT_Ctrl = ( 0x0004 | 0x0400 ); //IRQ5 2HZ AND IR2 timerB
// *P_INT_Ctrl = 0x0400; //只设置 IRQ2 TIMERB
*P_TimerB_Data = 0xffff-0x0008; //会自动重装
*P_TimerB_Ctrl = C_4096Hz;
__asm("int irq,fiq");
while(1)
{
*P_Watchdog_Clear = 0x0001;
if ( g_start_spk == true || g_start_realtime_spk == true ){
//按键 重计算 但自动和手动报时不允许同步
if ( g_start_realtime_spk == true && g_start_spk == false ){
ComposeSpkArr();
}
for( i = 0; i <= g_spk_arr_idx; i++ )
SPK( g_spk_arr[i] );
//全部报时完毕才能开始新的一组
g_start_spk = false;
g_start_realtime_spk = false;
}
if ( g_vdc_enable ){
////只设置一次
if ( !g_vdc_set_parameter ){
g_vdc_set_parameter = true;
*P_ADC_MUX_Ctrl = C_ADC_CH6;
*P_ADC_Ctrl = C_ADCE;
uiData = *P_ADC_LINEIN_Data;
}
a = *P_ADC_Ctrl;
b = *P_ADC_MUX_Ctrl;
c = *P_ADC;
d = *P_INT_Ctrl;
VoltageADC();
}
else{
//只设置一次
if ( g_vdc_set_parameter ){
g_vdc_set_parameter = false;
*P_ADC_Ctrl = C_ADCN;
}
}
}
}
__asm(".external F_FIQ_Service_SACM_A2000");
__asm(".external R_InterruptStatus");
__asm(".external G_INT_STATUS");
void FIQ(void)
{
__asm("int off");
__asm("[G_INT_STATUS] = R3");
__asm("R3 = 0x0404"); //IRQ5 2HZ AND IR2 timerB
__asm("[R_InterruptStatus] = R3");
__asm("R3 = [G_INT_STATUS]");
__asm("int irq,fiq");
if( *P_INT_Ctrl&0x2000 )
{
*P_INT_Clear = C_FIQ_TMA;
__asm("call F_FIQ_Service_SACM_A2000");
}
else if ( *P_INT_Ctrl & 0x0004 )
{
*P_INT_Clear = 0x0004;
}
else if ( *P_INT_Ctrl & 0x0400 )
{
*P_INT_Clear = 0x0400;
}
else if( *P_INT_Ctrl&0x0800 )
{
*P_INT_Clear = C_FIQ_TMB;
}
else
*P_INT_Clear = C_FIQ_PWM;
/*
__asm("int off");
__asm("R3 = 0x0006");
__asm("[0x702B] = R3"); //P_ADC_MUX_Ctrl C_ADC_CH6
__asm("int irq,fiq");*/
}
void IRQ2(void)
{
switch( g_led_index )
{
case 0:
F_Show( g_led_index, g_led_sec_lo );
g_led_index++;
break;
case 1:
if ( g_led_min_hi != 0 ||
g_led_min_lo!= 0 ||
g_led_sec_hi != 0 ){
F_Show( g_led_index, g_led_sec_hi );
}
g_led_index++;
break;
case 2:
if ( !g_vdc_enable ){
if ( g_led_min_hi != 0 ||
g_led_min_lo != 0 ){
F_Show( g_led_index, g_led_min_lo );
}
}
else{//无论如何都加.
F_Show( g_led_index, g_led_min_lo+10 );
}
g_led_index++;
break;
case 3:
if( g_led_min_hi != 0 ){
F_Show( g_led_index, g_led_min_hi );
}
g_led_index++;
break;
default:
break;
}
if ( g_led_index > 3 ){
g_led_index = 0;
}
//IOA4 为高电位
if ( *P_IOA_Data & 0x0001){
//计算按下键盘的持续时间
if ( g_switch_timecount >= 0 )
g_switch_timecount++;
if ( g_switch_timecount >= MIN_SWITCH_TIME ){
g_spk_time_count = 0;
g_led_index = 0;
//*P_IOA_Data &= ~(0x7f00);
//停止转换计时
g_switch_timecount = -1;
//放在这里比较安全
g_led_min_hi = 0;
g_led_min_lo = 0;
g_led_sec_hi = 0;
g_led_sec_lo = 0;
g_vdc_enable = !g_vdc_enable;
}
}
else{//松开按键之后
if ( g_switch_timecount > 0 &&
g_switch_timecount <= MIN_REALSPK_TIME ){
g_start_realtime_spk = true;
}
g_switch_timecount = 0;
}
if ( g_vdc_enable ){/*
if (g_old_min_lo == g_led_min_lo &&
g_old_min_hi == g_led_min_hi &&
g_old_sec_hi == g_led_sec_hi ){//最后一位小数可能有跳动,这里不比较他如 1.25V
if ( !g_already_spk_volage ){//没有自动报过电压,才开始计时
g_volage_stbtime++;
}
if ( g_volage_stbtime >= MIN_VOLAGE_STBTIME ){
g_volage_stbtime = 0;
}
g_start_realtime_spk = true; //报告一次稳定的电压
g_already_spk_volage = true;
}
else{
g_volage_stbtime = 0;
//前一次完全报告完成了才开始新的报告
if (! g_start_realtime_spk )
g_already_spk_volage = false;
g_old_min_lo = g_led_min_lo;
g_old_min_hi = g_led_min_hi;
g_old_sec_lo = g_led_sec_lo;
g_old_sec_hi = g_led_sec_hi;
}*/
}
*P_INT_Clear = 0x0400;
}
void IRQ5(void)
{
if(*P_INT_Ctrl & 0x0004 )
{//IRQ5 2HZ
__asm("int off");
g_base_2HZ_count++;
if( g_base_2HZ_count >= 2 )
{
g_base_2HZ_count = 0;
if ( g_vdc_enable == false ){
g_led_sec_lo++;
if ( g_led_sec_lo >= 10 ){
g_led_sec_lo = 0;
g_led_sec_hi++;
if ( g_led_sec_hi >= 6 ){
g_led_sec_hi = 0;
g_led_min_lo++;
if ( g_led_min_lo >= 10 ){
g_led_min_lo = 0;
g_led_min_hi++;
if ( g_led_min_hi >= 6 )
g_led_min_hi = 0;
}
}
}
g_spk_time_count++;
if ( g_spk_time_count >= SPK_TIME ){
g_spk_time_count = 0;
//准备一组新的报时数据 自动和手动报时不允许同步
if ( g_start_spk == false && g_start_realtime_spk == false ){
ComposeSpkArr();
g_start_spk = true;
}
}
}//g_vdc_enable==false
}
//必须清中断,否则会一直响应该中断
*P_INT_Clear = 0x0004;
__asm("int irq,fiq");
}
}
void VoltageADC(void)
{
int i = 0;
float fVoltage = 0;
float x =0;
float y = 0;
unsigned long uiData = 0;
for( i = 0; i < 16; i++ ){
*P_Watchdog_Clear = 0x0001;
uiData += AD();
}
uiData >>= 4; //计算平均值
fVoltage = (float)uiData/0xffc0*3.3;
//显示如 3.91 的数字
y = modff( fVoltage, &x );
__asm("int off");
if ( g_vdc_enable ){//屏蔽IRQ2中对min sec的修改
g_led_min_hi = 0;
g_led_min_lo = (unsigned int)x; ; //整数部分
g_led_sec_hi = (unsigned int)(y*100)/10; //小数部分×100十位
g_led_sec_lo = (unsigned int)(y*100)%10; //小数部分×10取个位
}
__asm("int irq,fiq");
}
unsigned int AD(void)
{
unsigned int uiData = 0;
while( !(*P_ADC_MUX_Ctrl&0x8000) );
uiData = *P_ADC_LINEIN_Data;
return(uiData&0xffc0); //b0-b4
}
void ComposeSpkArr(void)
{
__asm("int off");
if ( g_vdc_enable ){
//电压播报如: 嘀,二点一三
g_spk_arr_idx = 0;
g_spk_arr[g_spk_arr_idx] = SND_DI_BASE;
/*只测一位
if ( g_led_min_hi > 0 ){
g_spk_arr_idx++;
g_spk_arr[g_spk_arr_idx] = SND_NUM_BASE+g_led_min_hi;
g_spk_arr_idx++;
g_spk_arr[g_spk_arr_idx] = SND_NUM_BASE+10;
}*/
//不论如何 0 都要报
if ( g_led_min_lo >= 0 ){
g_spk_arr_idx++;
g_spk_arr[g_spk_arr_idx] = SND_NUM_BASE+g_led_min_lo;
}
//无论如何加"."
g_spk_arr_idx++;
g_spk_arr[g_spk_arr_idx] = SND_POINT;
if ( g_led_sec_hi >= 0 ){
g_spk_arr_idx++;
g_spk_arr[g_spk_arr_idx] = SND_NUM_BASE+g_led_sec_hi;
}
if ( g_led_sec_lo >= 0 ){
g_spk_arr_idx++;
g_spk_arr[g_spk_arr_idx] = SND_NUM_BASE+g_led_sec_lo;
}
}
else{
//嘀,现在时刻,21分20秒
g_spk_arr_idx = 0;
g_spk_arr[g_spk_arr_idx] = SND_DI_BASE;
g_spk_arr_idx++;
g_spk_arr[g_spk_arr_idx] = SND_REP_BASE;
if ( g_led_min_hi > 0 ){
g_spk_arr_idx++;
g_spk_arr[g_spk_arr_idx] = SND_NUM_BASE+g_led_min_hi;
g_spk_arr_idx++;
g_spk_arr[g_spk_arr_idx] = SND_NUM_BASE+10;
}
//不论如何 0 都不报
if ( g_led_min_lo > 0 ){
g_spk_arr_idx++;
g_spk_arr[g_spk_arr_idx] = SND_NUM_BASE+g_led_min_lo;
}
//分
if ( g_led_min_hi > 0 || g_led_min_lo > 0 ){
g_spk_arr_idx++;
g_spk_arr[g_spk_arr_idx] = SND_MIN;
}
if ( g_led_sec_hi > 0 ){
g_spk_arr_idx++;
g_spk_arr[g_spk_arr_idx] = SND_NUM_BASE+g_led_sec_hi;
g_spk_arr_idx++;
g_spk_arr[g_spk_arr_idx] = SND_NUM_BASE+10;
}
if ( g_led_sec_lo > 0 ){
g_spk_arr_idx++;
g_spk_arr[g_spk_arr_idx] = SND_NUM_BASE+g_led_sec_lo;
}
if ( g_led_sec_hi > 0 || g_led_sec_lo > 0 ){
g_spk_arr_idx++;
g_spk_arr[g_spk_arr_idx] = SND_SEC;
}
}
__asm("int irq,fiq");
}
void SPK(unsigned int index)
{
SACM_A2000_Initial(1);
__asm("int off");
//if ( *P_ADC_Ctrl & C_ADCE )
*P_DAC_Ctrl = 0x00a0;
__asm("int irq,fiq");
SACM_A2000_Play( index, DAC1+DAC2, Ramp_UpDn_On );
SACM_A2000_Volume(SPK_VOLUME);
while( SACM_A2000_Status()&0x0001 )
{
SACM_A2000_ServiceLoop();
*P_Watchdog_Clear = 0x0001;
}
SACM_A2000_Stop();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -