全局时钟初始化,定时器初始化,中断处理函数,中断向量结构,全局中断都没问题。
下面是定时中断处理函数。
@far @interrupt void irq_10ms_flag(void)
{
TIM5_SR1 = 0X0; //置位中断
freq =~freq;
//PF_ODR = ~PF_ODR; -----------------问题一
count_10ms--;
if (count_10ms <= 0)
count_10ms = 0;
time_freq++;
if (time_freq > 100) //修改time_freq为int
{
//PF_ODR = ~PF_ODR; --------------问题二
time_freq = 0; //为1000时处理时间,一秒处理一次
}
}
这个函数是没有问题的,但是我考虑到通用性,想通过在定时器中断处理函数中设置flag的方法,来延时。
于是,我屏蔽上面的问题一,问题二。
重新写了几个个函数。
函数一。
void delay_10ms(void)
{
unsigned char temp = freq;
while (temp == freq)
_asm("nop");
}
函数二。
void delay_10ms(unsigned char ten_ms)
{
count_10ms = ten_ms;
while (count_10ms)
_asm("nop");
}
再在主函数中写入
while(1)
{
PF_ODR = ~PF_ODR;
delay_10ms();
//delay_10ms(100);
}
这两个函数,不论哪一个都没有起到延时的作用。无论是上面的10ms还是下面的1秒,示波器显示全是稳定高电平。
如果将延时函数提到前面,就稳定低电平,也就是说delay_10ms这个函数死循环了。
5 个解决方案
#1
time_freq
count_10ms;
定义为
count_10ms;
定义为
volatile signed char count_10ms;
volatile signed char time_freq;
#2
测试了,没用。
经过其他测试,我在程序开始把time_freq = 0; freq = 0;
发现程序运行后,两者恒等于0。
换句话说,中断是运行的(PF_ODR = ~PF_ODR写在中断处理函数中没问题)。
中断函数中赋值给freq这两个全局变量也是没问题的,主楼问题二可以运行,说明计数没有问题。
但是退出中断处理函数后却没有保存。就是freq是个静态static变量一样。但是略有区别。
总结猜测就是
中断处理函数中的freq和我定义的全局freq虽然名字一样,但是却是不同的变量……
STVD4.3.5 + comic
#3
问题解决,我初始化了两个时间不同的溢出中断,TIM5,TIM6,
当初始化寄存器的时候,如果把TIM6_IER 和TIM6_CR1同时使能的话。会导致上面的问题。
贴出源码,看看是不是个例。
===========
mian.c
====stm8_interrupt_vector.c===
config.h是头文件和函数变量声明
原因未知。。。
当初始化寄存器的时候,如果把TIM6_IER 和TIM6_CR1同时使能的话。会导致上面的问题。
贴出源码,看看是不是个例。
===========
mian.c
/* MAIN.C file
*
* Copyright (c) 2002-2005 STMicroelectronics
*/
//#include "STM8S903K.h"
#include "config.h"
/*
* 全局变量定义
*/
volatile unsigned char count_10ms;
volatile char freq;
//volatile char time_freq;
void gpio_init(void)
{
/*
* 开背光,PF4,写1
*/
PF_DDR |=0X10;
PF_CR1 |=0X10;
PF_ODR |=0X10;
}
void clk_init(void)
{
/*对于内部高速时钟HSI[16MHz],其逻辑关系是HSI---[HSIDIV分频]---[时钟选择门]---
* 主时钟Fmaster---{[CPUDIV分频]---Fcpu时钟;其他外设时钟}
*/
CLK_ICKR = 0x01; //Internal clock control register。复位值,使能HSI时钟,快速唤醒禁止
CLK_ECKR = 0x00; //External clock control register。禁止。
CLK_SWR = 0xE1; //Clock master switch register。选择HSI为主时钟。
CLK_SWCR = 0x00; //Clock switch control register。时钟切换,中文数据手册似乎有误
/*Clock divider register。分频Fmaster和Fcpu。
* 默认是8和1,现在是2和1,因此Fmaster=8M,Fcpu=8M */
CLK_CKDIVR = 0x08;
CLK_PCKENR1 = 0xFF; //Peripheral clock gating register 1。Fmaster与外设时钟连接
CLK_PCKENR2 = 0x0; //同上
CLK_CSSR = 0x0; //Clock security system register。时钟安全检测关
CLK_CCOR = 0x0; //Configurable clock control register。时钟输出关闭
}
void var_init(void)
{
count_10ms = 0;
freq=0;
//time_freq =0;
}
void init(void)
{
gpio_init();
clk_init();
irq_init();
var_init();
}
void delay_10ms(unsigned char ten_ms)
{
count_10ms = ten_ms;
while(count_10ms);
}
main()
{
_asm("rim" );
init();
while (1)
{
delay_10ms(100);
PF_ODR = ~PF_ODR;
}
}
====stm8_interrupt_vector.c===
//#include "STM8S903K.h"
#include "config.h"
extern volatile unsigned char count_10ms;
extern volatile char freq;
typedef void @far (*interrupt_handler_t)(void);
struct interrupt_vector {
unsigned char interrupt_instruction;
interrupt_handler_t interrupt_handler;
};
@far @interrupt void NonHandledInterrupt (void)
{
/* in order to detect unexpected events during development,
it is recommended to set a breakpoint on the following instruction
*/
return;
}
void irq_init(void)
{
/*TIM5是16位简单定时器*/
/*HSI=16MHZ,Fcpu=Fmaster=8MHZ=Fck_psc*/
/*定时器时钟Fck_cnt由Fck_psc分频而来*/
TIM5_PSCR = 0X03; //分频8,计数器一次计数1us
TIM5_CNTRH = 0x0; //定时器计数值
TIM5_CNTRL = 0X0;
TIM5_ARRH = 0x27; //10000=0x2710,10ms中断一次
TIM5_ARRL = 0x10;
TIM5_IER = 0X01; //更新中断使能
TIM5_CR1 = 0X05; //使能计数器,使能溢出计数器
TIM5_EGR = 0X01; //立即开始一次中断
#if 0
/*TIM6是8位简单定时器*/
/*HSI=16MHZ,Fcpu=Fmaster=8MHZ=Fck_psc*/
//TIM6_PSCR = 0X06; //分频64,计数器一次计数8 ms
//TIM6_CNTR = 0x0; //定时器计数值
//TIM6_ARR = 0x3e; //125次1毫秒,
TIM6_IER = 0X01; //更新中断使能
TIM6_CR1 = 0X01; //使能计数器,使能溢出计数器
//TIM6_EGR = 0X01; //立即开始一次中断
#endif
}
/************************************************************************/
/* 功能:定时溢出中断处理,10ms一次的稳定中断
* 形参:无
* 返回:无
* 修改:2014-11-14
* 缘由:各种奇怪的问题 */
/************************************************************************/
@far @interrupt void irq_10ms_flag(void)
{
freq++;
if(freq == 100)
freq =0;
count_10ms--;
TIM5_SR1 &= ~0X01; //置位中断
}
extern void _stext(); /* startup routine */
struct interrupt_vector const _vectab[] = {
{0x82, (interrupt_handler_t)_stext}, /* reset */
{0x82, NonHandledInterrupt}, /* trap */
{0x82, NonHandledInterrupt}, /* irq0 */
{0x82, NonHandledInterrupt}, /* irq1 */
{0x82, NonHandledInterrupt}, /* irq2 */
{0x82, NonHandledInterrupt}, /* irq3 */
{0x82, NonHandledInterrupt}, /* irq4 */
{0x82, NonHandledInterrupt}, /* irq5 */
{0x82, NonHandledInterrupt}, /* irq6 */
{0x82, NonHandledInterrupt}, /* irq7 */
{0x82, NonHandledInterrupt}, /* irq8 */
{0x82, NonHandledInterrupt}, /* irq9 */
{0x82, NonHandledInterrupt}, /* irq10 */
{0x82, NonHandledInterrupt}, /* irq11 */
{0x82, NonHandledInterrupt}, /* irq12 */
{0x82, irq_10ms_flag}, /* irq13 */
{0x82, NonHandledInterrupt}, /* irq14 */
{0x82, NonHandledInterrupt}, /* irq15 */
{0x82, NonHandledInterrupt}, /* irq16 */
{0x82, NonHandledInterrupt}, /* irq17 */
{0x82, NonHandledInterrupt}, /* irq18 */
{0x82, NonHandledInterrupt}, /* irq19 */
{0x82, NonHandledInterrupt}, /* irq20 */
{0x82, NonHandledInterrupt}, /* irq21 */
{0x82, NonHandledInterrupt}, /* irq22 */
{0x82, NonHandledInterrupt}, /* irq23 */
{0x82, NonHandledInterrupt}, /* irq24 */
{0x82, NonHandledInterrupt}, /* irq25 */
{0x82, NonHandledInterrupt}, /* irq26 */
{0x82, NonHandledInterrupt}, /* irq27 */
{0x82, NonHandledInterrupt}, /* irq28 */
{0x82, NonHandledInterrupt}, /* irq29 */
};
config.h是头文件和函数变量声明
#ifndef _CONFIG_H
#define _CONFIG_H
///////////////////////官方库文件///////////////////////////////////
#include "STM8S903K.h"
@far @interrupt void irq_10ms_flag(void);
void irq_init(void);
#endif
原因未知。。。
#4
/**虽然怪怪的,但程序逻辑没有问题,不确认楼主开启中断后再去初始化行不行,但正常是这样的初始化**/
main()
{
_asm("sim" ); //禁止中断
init();
_asm("rim" );
while (1)
{
delay_10ms(100);
PF_ODR = ~PF_ODR;
}
}
main()
{
_asm("sim" ); //禁止中断
init();
_asm("rim" );
while (1)
{
delay_10ms(100);
PF_ODR = ~PF_ODR;
}
}
#5
//我这么写一点问题都没有。
#pragma vector=TIM4_OVR_UIF_vector
__interrupt void TIM4_OVR_UIF_IRQHandler(void)
{
TIM4_SR=0x00;
count_250us++;
if(count_250us%4==0){
ms_count++;
}
if(count_250us==4000){
System_Time++; //+1/s
count_250us=0;
}
}
void delay_ms(unsigned int time)
{
ms_count=0;
while(ms_count<time);
}
#pragma vector=TIM4_OVR_UIF_vector
__interrupt void TIM4_OVR_UIF_IRQHandler(void)
{
TIM4_SR=0x00;
count_250us++;
if(count_250us%4==0){
ms_count++;
}
if(count_250us==4000){
System_Time++; //+1/s
count_250us=0;
}
}
void delay_ms(unsigned int time)
{
ms_count=0;
while(ms_count<time);
}
#1
time_freq
count_10ms;
定义为
count_10ms;
定义为
volatile signed char count_10ms;
volatile signed char time_freq;
#2
测试了,没用。
经过其他测试,我在程序开始把time_freq = 0; freq = 0;
发现程序运行后,两者恒等于0。
换句话说,中断是运行的(PF_ODR = ~PF_ODR写在中断处理函数中没问题)。
中断函数中赋值给freq这两个全局变量也是没问题的,主楼问题二可以运行,说明计数没有问题。
但是退出中断处理函数后却没有保存。就是freq是个静态static变量一样。但是略有区别。
总结猜测就是
中断处理函数中的freq和我定义的全局freq虽然名字一样,但是却是不同的变量……
STVD4.3.5 + comic
#3
问题解决,我初始化了两个时间不同的溢出中断,TIM5,TIM6,
当初始化寄存器的时候,如果把TIM6_IER 和TIM6_CR1同时使能的话。会导致上面的问题。
贴出源码,看看是不是个例。
===========
mian.c
====stm8_interrupt_vector.c===
config.h是头文件和函数变量声明
原因未知。。。
当初始化寄存器的时候,如果把TIM6_IER 和TIM6_CR1同时使能的话。会导致上面的问题。
贴出源码,看看是不是个例。
===========
mian.c
/* MAIN.C file
*
* Copyright (c) 2002-2005 STMicroelectronics
*/
//#include "STM8S903K.h"
#include "config.h"
/*
* 全局变量定义
*/
volatile unsigned char count_10ms;
volatile char freq;
//volatile char time_freq;
void gpio_init(void)
{
/*
* 开背光,PF4,写1
*/
PF_DDR |=0X10;
PF_CR1 |=0X10;
PF_ODR |=0X10;
}
void clk_init(void)
{
/*对于内部高速时钟HSI[16MHz],其逻辑关系是HSI---[HSIDIV分频]---[时钟选择门]---
* 主时钟Fmaster---{[CPUDIV分频]---Fcpu时钟;其他外设时钟}
*/
CLK_ICKR = 0x01; //Internal clock control register。复位值,使能HSI时钟,快速唤醒禁止
CLK_ECKR = 0x00; //External clock control register。禁止。
CLK_SWR = 0xE1; //Clock master switch register。选择HSI为主时钟。
CLK_SWCR = 0x00; //Clock switch control register。时钟切换,中文数据手册似乎有误
/*Clock divider register。分频Fmaster和Fcpu。
* 默认是8和1,现在是2和1,因此Fmaster=8M,Fcpu=8M */
CLK_CKDIVR = 0x08;
CLK_PCKENR1 = 0xFF; //Peripheral clock gating register 1。Fmaster与外设时钟连接
CLK_PCKENR2 = 0x0; //同上
CLK_CSSR = 0x0; //Clock security system register。时钟安全检测关
CLK_CCOR = 0x0; //Configurable clock control register。时钟输出关闭
}
void var_init(void)
{
count_10ms = 0;
freq=0;
//time_freq =0;
}
void init(void)
{
gpio_init();
clk_init();
irq_init();
var_init();
}
void delay_10ms(unsigned char ten_ms)
{
count_10ms = ten_ms;
while(count_10ms);
}
main()
{
_asm("rim" );
init();
while (1)
{
delay_10ms(100);
PF_ODR = ~PF_ODR;
}
}
====stm8_interrupt_vector.c===
//#include "STM8S903K.h"
#include "config.h"
extern volatile unsigned char count_10ms;
extern volatile char freq;
typedef void @far (*interrupt_handler_t)(void);
struct interrupt_vector {
unsigned char interrupt_instruction;
interrupt_handler_t interrupt_handler;
};
@far @interrupt void NonHandledInterrupt (void)
{
/* in order to detect unexpected events during development,
it is recommended to set a breakpoint on the following instruction
*/
return;
}
void irq_init(void)
{
/*TIM5是16位简单定时器*/
/*HSI=16MHZ,Fcpu=Fmaster=8MHZ=Fck_psc*/
/*定时器时钟Fck_cnt由Fck_psc分频而来*/
TIM5_PSCR = 0X03; //分频8,计数器一次计数1us
TIM5_CNTRH = 0x0; //定时器计数值
TIM5_CNTRL = 0X0;
TIM5_ARRH = 0x27; //10000=0x2710,10ms中断一次
TIM5_ARRL = 0x10;
TIM5_IER = 0X01; //更新中断使能
TIM5_CR1 = 0X05; //使能计数器,使能溢出计数器
TIM5_EGR = 0X01; //立即开始一次中断
#if 0
/*TIM6是8位简单定时器*/
/*HSI=16MHZ,Fcpu=Fmaster=8MHZ=Fck_psc*/
//TIM6_PSCR = 0X06; //分频64,计数器一次计数8 ms
//TIM6_CNTR = 0x0; //定时器计数值
//TIM6_ARR = 0x3e; //125次1毫秒,
TIM6_IER = 0X01; //更新中断使能
TIM6_CR1 = 0X01; //使能计数器,使能溢出计数器
//TIM6_EGR = 0X01; //立即开始一次中断
#endif
}
/************************************************************************/
/* 功能:定时溢出中断处理,10ms一次的稳定中断
* 形参:无
* 返回:无
* 修改:2014-11-14
* 缘由:各种奇怪的问题 */
/************************************************************************/
@far @interrupt void irq_10ms_flag(void)
{
freq++;
if(freq == 100)
freq =0;
count_10ms--;
TIM5_SR1 &= ~0X01; //置位中断
}
extern void _stext(); /* startup routine */
struct interrupt_vector const _vectab[] = {
{0x82, (interrupt_handler_t)_stext}, /* reset */
{0x82, NonHandledInterrupt}, /* trap */
{0x82, NonHandledInterrupt}, /* irq0 */
{0x82, NonHandledInterrupt}, /* irq1 */
{0x82, NonHandledInterrupt}, /* irq2 */
{0x82, NonHandledInterrupt}, /* irq3 */
{0x82, NonHandledInterrupt}, /* irq4 */
{0x82, NonHandledInterrupt}, /* irq5 */
{0x82, NonHandledInterrupt}, /* irq6 */
{0x82, NonHandledInterrupt}, /* irq7 */
{0x82, NonHandledInterrupt}, /* irq8 */
{0x82, NonHandledInterrupt}, /* irq9 */
{0x82, NonHandledInterrupt}, /* irq10 */
{0x82, NonHandledInterrupt}, /* irq11 */
{0x82, NonHandledInterrupt}, /* irq12 */
{0x82, irq_10ms_flag}, /* irq13 */
{0x82, NonHandledInterrupt}, /* irq14 */
{0x82, NonHandledInterrupt}, /* irq15 */
{0x82, NonHandledInterrupt}, /* irq16 */
{0x82, NonHandledInterrupt}, /* irq17 */
{0x82, NonHandledInterrupt}, /* irq18 */
{0x82, NonHandledInterrupt}, /* irq19 */
{0x82, NonHandledInterrupt}, /* irq20 */
{0x82, NonHandledInterrupt}, /* irq21 */
{0x82, NonHandledInterrupt}, /* irq22 */
{0x82, NonHandledInterrupt}, /* irq23 */
{0x82, NonHandledInterrupt}, /* irq24 */
{0x82, NonHandledInterrupt}, /* irq25 */
{0x82, NonHandledInterrupt}, /* irq26 */
{0x82, NonHandledInterrupt}, /* irq27 */
{0x82, NonHandledInterrupt}, /* irq28 */
{0x82, NonHandledInterrupt}, /* irq29 */
};
config.h是头文件和函数变量声明
#ifndef _CONFIG_H
#define _CONFIG_H
///////////////////////官方库文件///////////////////////////////////
#include "STM8S903K.h"
@far @interrupt void irq_10ms_flag(void);
void irq_init(void);
#endif
原因未知。。。
#4
/**虽然怪怪的,但程序逻辑没有问题,不确认楼主开启中断后再去初始化行不行,但正常是这样的初始化**/
main()
{
_asm("sim" ); //禁止中断
init();
_asm("rim" );
while (1)
{
delay_10ms(100);
PF_ODR = ~PF_ODR;
}
}
main()
{
_asm("sim" ); //禁止中断
init();
_asm("rim" );
while (1)
{
delay_10ms(100);
PF_ODR = ~PF_ODR;
}
}
#5
//我这么写一点问题都没有。
#pragma vector=TIM4_OVR_UIF_vector
__interrupt void TIM4_OVR_UIF_IRQHandler(void)
{
TIM4_SR=0x00;
count_250us++;
if(count_250us%4==0){
ms_count++;
}
if(count_250us==4000){
System_Time++; //+1/s
count_250us=0;
}
}
void delay_ms(unsigned int time)
{
ms_count=0;
while(ms_count<time);
}
#pragma vector=TIM4_OVR_UIF_vector
__interrupt void TIM4_OVR_UIF_IRQHandler(void)
{
TIM4_SR=0x00;
count_250us++;
if(count_250us%4==0){
ms_count++;
}
if(count_250us==4000){
System_Time++; //+1/s
count_250us=0;
}
}
void delay_ms(unsigned int time)
{
ms_count=0;
while(ms_count<time);
}