/*
* 功能:测LSI的频率
* 时间:2015.5.20
*
*/
#include"STM8S105c_s.h"
#define uchar unsigned char
#define NOP() _asm("nop")
unsigned int beep_cap_data_new;
unsigned int beep_cap_data_old;
unsigned int beep_period;
unsigned int beep_hz;
unsigned char isCaptureOver=0;
_Bool CLK @PA_ODR:4;
_Bool STB @PA_ODR:5;
_Bool DATA @PA_ODR:6;
extern @far @interrupt void signal_vapture_irp(void);
void beep_init(void);
const unsigned char b_TAB_SEG[]=
{
0x3F, //;0
0x06, //;1
0x5B, //;2
0x4F, //;3
0x66, //;4
0x6D, //;5
0x7D, //;6
0x07, //;7
0x7F, //;8
0x6F, //;9
0x77, //;A
0x7C, //;b
0x39, //;C
0x5E, //;d
0x79, //;E
0x71, //;F
0x40, //- 16
0x76, //H 17
0x73, //P 18
0x00 //19 no display
};
void delayUS(void)
{
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
}
void DelayMS(unsigned int ms)
{
unsigned char i;
while(ms!=0)
{
for(i=0;i<250;i++);
for(i=0;i<75;i++);
ms--;
}
}
void sent8bit(uchar temp)
{
uchar i=8,num1=0;
num1=temp;
STB=0;
for(i=8;i>0;i--)
{
CLK=0;
DATA=num1&0x01;
NOP();
NOP();
CLK=1;
NOP();
NOP();
num1=num1>>1;
}
}
void EXC2618_Init(void)
{
STB=1;
DATA=1;
CLK=1;
PA_DDR=0X70;
PA_CR1=0X70;
PA_CR2=0XFF;
sent8bit(0X03);
delayUS();
STB=1;
sent8bit(0X89);
delayUS();
STB=1;
sent8bit(0X44);
delayUS();
STB=1;
}
void send_data(uchar add,uchar data)
{
sent8bit(add);
delayUS();
sent8bit(data);
delayUS();
STB=1;
delayUS();
}
main()
{ int i;
CLK_SWR=0xE1;//配置内部16M时钟
CLK_CKDIVR=0x00;
PD_DDR=PD_DDR|0x01;//PD0口用于控制蜂鸣器的开关
PD_CR1=0x01;
PD_CR2=0x04;
PD_ODR=PD_ODR|0x00;//开蜂鸣器
CLK_ICKR=CLK_ICKR|0x08;//启动LSI时钟
while((CLK_ICKR&0x10)==0);
beep_init();//TIM3捕获初始化
for(i=0;i<10;i++)//蜂鸣器开启时间
{
DelayMS(500);
}
PD_ODR=PD_ODR&0xFE;//关闭蜂鸣器
_asm("rim");//开全局中断
while (1)
{
if(isCaptureOver)//如果捕获完成则对数据进行处理
{
_asm("sim");//关闭中断,否则数据无法显示(原因不明)
beep_hz=(unsigned char)(16000/beep_period);//计算频率单位KHZ
//beep_hz=beep_period;
EXC2618_Init();//初始化设置
send_data(0xc2,b_TAB_SEG[(beep_hz%1000/100)]);
send_data(0xca,b_TAB_SEG[(beep_hz%100/10)]);
send_data(0xcc,b_TAB_SEG[(beep_hz%10)]);
send_data(0xc0,b_TAB_SEG[15]);
_asm("rim");//重新开中断(调试发现捕获中断函数仍无法进入)
TIM3_CNTRH = 0x00;//清零计数器高8位
TIM3_CNTRL = 0x00;//清零计数器低8位
TIM3_IER |= 0x02;//CC1IE=1,使能捕获/比较1中断
TIM3_CR1 |= 0x01;//使能定时/计数器
isCaptureOver = 0;
}
}
}
void beep_init(void)
{
TIM3_CNTRH = 0x00;//清零计数器高8位
TIM3_CNTRL = 0x00;//清零计数器低8位
TIM3_PSCR = 0x00;//时钟分频不分频
TIM3_CCER1&= 0xFE;//清零TIM3_CCER1中的CC1E位,之后才可配置TIM3_CCMR1
TIM3_CCMR1 = 0x01;//配置TIM3_CCMR1中的CC1S位为1,CC1通道配置为输入,IC1映射到TI1FP1上
TIM3_CCER1&= 0xfd;//上升沿或者高电平触发
//TIM3_CCER1|= 0x02;//下降沿或者挖低电平触发
TIM3_IER|= 0x02;//CC1IE=1,使能捕获/比较1中断
TIM3_CCER1|= 0x01;//捕获使能
TIM3_CR1|= 0x01;//使能计时器/定时器
CLK_PCKENR2|=0x04;//开启AWU使能
AWU_CSR |= 0x01;//将LSI的内部时钟连接到TIM3定时器的ICAP1
BEEP_CSR = 0xAE;//配置BEEP IO输出4K频率信号驱动蜂鸣器
//0x2e为输出1KHZ,0x6e为输出2KHZ
}
@far @interrupt void signal_vapture_irp(void)
{
if(TIM3_SR1&0x02)
{
TIM3_SR1 &= 0xFD;//清除CC1IF标志
if(beep_cap_data_old == 0x00)
{//第一次捕获中断来临
beep_cap_data_old = TIM3_CCR1H;//先读取高8位数据
beep_cap_data_old = (unsigned int)(beep_cap_data_old<<8) + TIM3_CCR1L;//再读取低8位数据
//TIM3_CCER1|= 0x02;//下降沿或者挖低电平触发
//TIM3_CCER1&= 0xfd;//上升沿或者高电平触发
}
else
{
//第二次捕获中断来临
beep_cap_data_new = TIM3_CCR1H;//先读取高8位数据
beep_cap_data_new = (unsigned int)(beep_cap_data_new<<8) + TIM3_CCR1L;//再读取低8位数据
TIM3_IER &= 0xFD;//禁止通道1捕获/比较中断
TIM3_CR1 &= 0xFE;//停止计数器
if(beep_cap_data_new > beep_cap_data_old)
beep_period = (beep_cap_data_new - beep_cap_data_old);
else
beep_period = 0xFFFF + beep_cap_data_new - beep_cap_data_old;
beep_cap_data_old = 0x00;
isCaptureOver = 1;//捕获中断完成标志
}
}
}
为什么TIM3的输入捕获进行了一次就结束了,显示不会进行更新,我原想让它实时动态显示的,问题出在了哪里了。调试发现会停在第二个 _asm("rim")处并进入到中断向量表文件的return语句出不去。 |