OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3004|回复: 3

延时函数问题和定时器中断问题

[复制链接]

2

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2018-8-10
在线时间
7 小时
发表于 2018-8-16 14:54:49 | 显示全部楼层 |阅读模式
1金钱
我是使用原子的延时函数,在主函数中延时1秒,再向串口1发送数据,问题是我在串口中看到一直不停的发送没有延时1秒钟,我在定时器中的中断函数调用别的子函数(子函数中有延时程序),还有就是,我在定时器的中断函数中改变定时时间和停止中断,但是如果是停止中断的话就卡在内面出不来,如果是改变的话延时函数也出现问题。我这个是读取SHT20的程序,中间等待的时间我用定时器来解决,这样就可以免得浪费CPU的时间和等待。现在就是读取不出数据,和延时时间也出现问题。

#include "sht20.h"
#include "sys.h"
#include "delay.h"
#include "led.h"

u8 R_Flag=0,T_Flag=0;        //湿度,温度定时标志位

u16 Humidity,Temperature;        //湿度,温度,数据存储变量

/*****************************************
名称:SHT2x_init()
功能:STH20模块初始化&软复位程序
*****************************************/
void SHT2x_init(void)
{
//        IIC_Init();
        IIC_Start();                                //STH20启动
        IIC_Send_Byte(add_w);                //发送地址写程序
        IIC_getACK();                                //接收应答程序
        IIC_Send_Byte(RST_code);        //发送软复位程序
        IIC_getACK();                                //接收应答程序
        IIC_Stop();                                        //发送停止程序
        delay_ms(15);                                //延时15mS
        IIC_SCL = 1;                                //STH20时钟口置高
        IIC_SDA = 1;                                //STH20数据口置高
}

// 测量分辨率设置 RH 12 BIT、T 14 BIT,测量时间RH29ms、T85ms
/*****************************************
名称:SHT2x_Resolution()
功能:设置STH20模块分辨率
*****************************************/
void SHT2x_Resolution(void)
{
        IIC_Start();                                //STH20启动
        IIC_Send_Byte(add_w);                //发送地址写程序
        IIC_getACK();                                //接收应答程序
        IIC_Send_Byte(user_code_w);        //向用户寄存器写命令
        IIC_getACK();                                //接收应答程序
        IIC_Send_Byte(0x3A);                //向用户寄存器写数据
        IIC_getACK();                                //接收应答程序
        IIC_getACK();                                //接收应答程序
        IIC_Stop();                                        //发送停止程序
}

/*****************************************
名称:unsigned int RH_Result()
功能:读取STH20湿度数据
返回:返回湿度RH
*****************************************/
void RH_Result(void)
{
//        u16 RH_Data;                                                //定义一个2字节变量
//        u32 RH=0;                                                        //定义一个4字节变量
        IIC_Start();                                                //STH20启动
        IIC_Send_Byte(add_w);                                //发送地址写程序
        IIC_getACK();                                                //接收应答程序
        IIC_Send_Byte(RH_code);                                //发送读取湿度数据
        IIC_getACK();                                                //接收应答程序
        IIC_Start();                                                //STH20启动
        IIC_Send_Byte(add_r);                                //发送读操作
        IIC_getACK();                                                //接收应答程序
       
        R_Flag = 1;                                                        //设置读取温度标志位为1
        T_Flag = 0;
       
        TIM4_Int_Init(289,7199);                        //设置定时时间为29MS
//        TIM_Cmd(TIM4, ENABLE);                                 //使能TIMx外设
//        delay_ms(29);                                                //等待延时时间
/*        RH_Data=IIC_Read_Byte();                        //读取湿度高位数据
        IIC_Ack();                                                        //发送应答程序
        RH_Data=RH_Data<<8;                                        //把高位数据向左移8位
        RH_Data=RH_Data|IIC_Read_Byte();        //再读取湿度低位数据再和高位数据结合再一起
        IIC_NAck();                                                        //非答应程序
        IIC_Stop();                                                        //发送停止程序
        RH_Data=RH_Data&0xfffc;                                //去除数据最后二位
        RH=RH_Data*12500L;                                        //乘以12500L表示去小数,分辨率为0.04
        RH=RH>>16;                                                        //除2的16次方
        RH=RH-600;                                                        //减去600
        return RH;                                                        //返回数据
        */
}

/*****************************************
名称:unsigned int T_Result()
功能:读取STH20温度数据
返回:返回温度T
*****************************************/
void T_Result(void)
{
//        u16 T_Data;                                                        //定义一个2字节变量
//        u32 T=0;                                                        //定义一个4字节变量
        IIC_Start();                                                //STH20启动
        IIC_Send_Byte(add_w);                                //发送地址写程序
        IIC_getACK();                                                //接收应答程序
        IIC_Send_Byte(T_code);                                //发送读取温度数据
        IIC_getACK();                                                //接收应答程序
        IIC_Start();                                                //STH20启动
        IIC_Send_Byte(add_r);                                //发送读操作
        IIC_getACK();                                                //接收应答程序
       
        T_Flag = 1;                                                        //设置读取温度标志位为1
        R_Flag = 0;
        TIM4_Int_Init(849,7199);                        //设置定时时间为85MS
       
//        TIM_Cmd(TIM4, ENABLE);                          //使能TIMx外设
/*        delay_ms(85);                                                //等待延时时间
        T_Data=IIC_Read_Byte();                                //读取温度高位数据
        IIC_Ack();                                                        //发送应答程序
        T_Data=T_Data<<8;                                        //把高位数据向左移8位
        T_Data=T_Data|IIC_Read_Byte();                //再读取温度低位数据再和高位数据结合再一起
        IIC_NAck();                                                        //非答应程序
        IIC_Stop();                                                        //发送停止程序
        T_Data=T_Data&0xfffE;                                //去除数据最后一位
        T=T_Data*17572L;                                        //乘以12500L表示去小数,分辨率为0.01
        T=T>>16;                                                        //除2的16次方
        T=T-4685;                                                        //减去4685
        return T;                                                        //返回数据
        */
}

//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器4!
void TIM4_Int_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //时钟使能

        TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         计数到5000为500ms
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率  
        TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
       
        TIM_ClearITPendingBit(TIM4, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源
        TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);        //使能定时器4中断

        NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;  //TIM4中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  //从优先级3级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

        TIM_Cmd(TIM4, ENABLE);  //使能TIMx外设                         
}

void TIM4_IRQHandler(void)   //TIM4中断
{
        u16 RH_Data,T_Data;                                                        //定义两个2字节变量
        u32 RH=0,T=0;                                                                //定义两个4字节变量
        if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
        {
                if(R_Flag == 1)                                                        //如果湿度标志位为1
                {
                        R_Flag = 0;                                                        //清除湿度标志位
                        RH_Data=IIC_Read_Byte();                        //读取湿度高位数据
                        IIC_Ack();                                                        //发送应答程序
                        RH_Data=RH_Data<<8;                                        //把高位数据向左移8位
                        RH_Data=RH_Data|IIC_Read_Byte();        //再读取湿度低位数据再和高位数据结合再一起
                        IIC_NAck();                                                        //非答应程序
                        IIC_Stop();                                                        //发送停止程序
                        RH_Data=RH_Data&0xfffc;                                //去除数据最后二位
                        RH=RH_Data*12500L;                                        //乘以12500L表示去小数,分辨率为0.04
                        RH=RH>>16;                                                        //除2的16次方
                        RH=RH-600;                                                        //减去600
                        Humidity = RH;                                                //返回数据
                        TIM_ClearITPendingBit(TIM4, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源
                        T_Result();                                                        //读取温度数据
                //        WIFI_LED = ~WIFI_LED;
                        WIFI_LED = 0;
                }
               
                if(T_Flag == 1)                                                        //如果温度标志位为1
                {
                        T_Flag = 0;                                                        //清除温度标志位
                        T_Data=IIC_Read_Byte();                                //读取温度高位数据
                        IIC_Ack();                                                        //发送应答程序
                        T_Data=T_Data<<8;                                        //把高位数据向左移8位
                        T_Data=T_Data|IIC_Read_Byte();                //再读取温度低位数据再和高位数据结合再一起
                        IIC_NAck();                                                        //非答应程序
                        IIC_Stop();                                                        //发送停止程序
                        T_Data=T_Data&0xfffE;                                //去除数据最后一位
                        T=T_Data*17572L;                                        //乘以17572L表示去小数,分辨率为0.01
                        T=T>>16;                                                        //除2的16次方
                        T=T-4685;                                                        //减去4685
                        Temperature = T;                                        //返回数据
                        Bluetooth_LED = 0;
                       
                //        Bluetooth_LED = ~Bluetooth_LED;
                //        TIM_Cmd(TIM4, DISABLE);                          //停止TIMx外设       
                        TIM_ClearITPendingBit(TIM4, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源
                        RH_Result();
                }
        //        TIM_ClearITPendingBit(TIM4, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源
        }
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

57

主题

1680

帖子

3

精华

资深版主

Rank: 8Rank: 8

积分
4306
金钱
4306
注册时间
2018-6-30
在线时间
808 小时
发表于 2018-8-16 19:54:24 | 显示全部楼层
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2018-8-17 01:35:53 | 显示全部楼层
你真想高效利用CPU的话, 整个OS吧。
回复

使用道具 举报

2

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2018-8-10
在线时间
7 小时
 楼主| 发表于 2018-8-17 01:38:24 | 显示全部楼层
正点原子 发表于 2018-8-17 01:35
你真想高效利用CPU的话, 整个OS吧。

不是现在主要是出现了问题,要解决而已,我在51单片机上面已经实现了这些功能和操作了,现在是该在STM32上面看看,这样的话比较。但是现在STM32上面出现了我说的问题而已,就想看看各位有没有遇到相同的问题,看看大家是怎么解决。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-18 19:49

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表