打印
[uCOS/RTOS]

KEIL 全局变量 值改变

[复制链接]
3165|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
最近一具项目,软件用了UCOSII,里面用到RTC,RTC时间可以正常的读取,值也正确,但把时分秒分秒分别赋给不同的变量(USB_hour/USB_min)后,用Sprintf函数把(USB_hour/USB_min)赋值给数组System_time,此时再观察(USB_hour/USB_min),发现 hour的值被改变了, USB_min的值没有被改变。程序其它的地方没有处理(USB_hour/USB_min),这是为什么呢?
请指点!谢谢!
对下是我的RTC部分代码
RTC_TimeTypeDef         RTC_TimeTypeInitStructure;
RTC_DateTypeDef RTC_DateStruct;
u8 System_time[5]={0x31,0x32,':',0x30,0x30};
volatile u8 USB_hour;
volatile u8 USB_min;
#ifdef        RTCTask       
__align(8) OS_STK   TaskStk_RTC[RTC_STK_SIZE];
void Task_RTC(void *p_arg)
{
        u8 i_flag;

        (void)p_arg;
        My_RTC_Init();                                 //初始化RTC
  while (1)
  {
                if(CHTcal_flag==0xAA)
                {
                        if(Hour_check<=12)
                        RTC_Set_Time(Hour_check,Min_check,00,RTC_H12_AM);        //设置时间
                        else
                        RTC_Set_Time(Hour_check,Min_check,00,RTC_H12_PM);        //设置时间       
                        CHTcal_flag=0x55;
                }
                RTC_GetTime(RTC_Format_BIN,&RTC_TimeTypeInitStructure);       
                USB_hour=RTC_TimeTypeInitStructure.RTC_Hours;
                USB_min=RTC_TimeTypeInitStructure.RTC_Minutes;
                memset(System_time,0,5);
                sprintf((char*)System_time,"%2d%s%2d",USB_hour,":",USB_min);
                for(i_flag=0;i_flag<5;i_flag++)
                {
                        if(System_time[i_flag]==0x20) System_time[i_flag]=0x30;
                }
                OSTimeDlyHMSM (0,0,1,0);  
        }  
}

相关帖子

沙发
qqqlijie|  楼主 | 2015-3-12 10:26 | 只看该作者
沙发是我的了

使用特权

评论回复
板凳
liuxiang5119| | 2015-3-16 00:15 | 只看该作者
可以单步调试么  如果可以的话观察下memset(System_time,0,5);之前 USB_hour、USB_min  然后单步到sprintf,这样就可以确定是sprintf本身转换问题还是说你在中途有被其他改变过

使用特权

评论回复
地板
qqqlijie|  楼主 | 2015-3-17 15:06 | 只看该作者
liuxiang5119 发表于 2015-3-16 00:15
可以单步调试么  如果可以的话观察下memset(System_time,0,5);之前 USB_hour、USB_min  然后单步到sprintf ...

单步调试过了,是在sprintf 后 USB_hour变成0的,USB_min没有变化,
怀疑是SPrintf的问题,我把sprintf((char*)System_time,"%2d%s%2d",USB_hour,":",USB_min); 这行代码改成了
sprintf((char*)System_time,"%2d%s%2d",RTC_TimeTypeInitStructure.RTC_Hours,":",USB_min);
单步调试的结果还是一样的,USB_hour在sprintf后还是会变成0
在程序的其它地方没有用到USB_hour

使用特权

评论回复
5
mazhao141| | 2015-3-18 11:32 | 只看该作者
不要用sprintf

使用特权

评论回复
6
ayb_ice| | 2015-3-19 14:37 | 只看该作者
应该是函数不可重入引起的,

可以用信号量解决

使用特权

评论回复
7
liuxiang5119| | 2015-3-19 14:52 | 只看该作者
本帖最后由 liuxiang5119 于 2015-3-19 14:56 编辑
qqqlijie 发表于 2015-3-17 15:06
单步调试过了,是在sprintf 后 USB_hour变成0的,USB_min没有变化,
怀疑是SPrintf的问题,我把sprintf(( ...

那么就可以确定是sprintf 上边出错的   直接用字符数组拼起来得了         当然最好是找一下为什么SPrintf会出错会不会是内存不对齐引起的    或者你可以把那两个参数更改成int类型的试下

使用特权

评论回复
8
qqqlijie|  楼主 | 2015-3-23 16:32 | 只看该作者
liuxiang5119 发表于 2015-3-19 14:52
那么就可以确定是sprintf 上边出错的   直接用字符数组拼起来得了         当然最好是找一下为什么SPrintf ...

sprintf 的操作对像是 char 类型,与定义的USB_hour USB_min 的类型是一样的啊

使用特权

评论回复
9
qqqlijie|  楼主 | 2015-3-23 16:36 | 只看该作者
有一个非常不解的现像,我在系统的其它任务里增加了一些后,今天发现,以上的那种错误现象不存在了,但是我并没有修改这部分功能啊,完全没有操作这部分的变量和函数。越来越不解

使用特权

评论回复
10
qqqlijie|  楼主 | 2015-3-23 16:37 | 只看该作者

请问sprintf 函数有什么BUG吗?

使用特权

评论回复
11
qqqlijie|  楼主 | 2015-3-23 16:42 | 只看该作者
ayb_ice 发表于 2015-3-19 14:37
应该是函数不可重入引起的,

可以用信号量解决

sprintf 函数不可 重入吗?
我的系统任务的其它地方没有修改USB_hour USB_Min 这些变量的,完全没有,只是把在其它地方把USB_hour USB_Min赋值给了其它变量

使用特权

评论回复
12
ayb_ice| | 2015-3-23 16:53 | 只看该作者
qqqlijie 发表于 2015-3-23 16:42
sprintf 函数不可 重入吗?
我的系统任务的其它地方没有修改USB_hour USB_Min 这些变量的,完全没有,只 ...

我不敢肯定是否重入,但在KEIL里是不重入的

使用特权

评论回复
13
ayb_ice| | 2015-3-23 16:59 | 只看该作者
qqqlijie 发表于 2015-3-23 16:42
sprintf 函数不可 重入吗?
我的系统任务的其它地方没有修改USB_hour USB_Min 这些变量的,完全没有,只 ...

RT:

未命名.jpg (82.59 KB )

未命名.jpg

使用特权

评论回复
14
qqqlijie|  楼主 | 2015-3-31 15:56 | 只看该作者
恩,以后尽量少用全局变量就是了;

使用特权

评论回复
15
hgjinwei| | 2015-4-1 22:13 | 只看该作者
u8 System_time[5]={0x31,0x32,':',0x30,0x30};
volatile u8 USB_hour;
volatile u8 USB_min;

sprintf((char*)System_time,"%2d%s%2d",USB_hour,":",USB_min);

sprintf 需要的System_time空间至少6字节: '0','0',':','0','0','\0';
你的System_time空间只有5字节,当然要把后面那个USB_hour变为'\0'啦

你试试将
volatile u8 USB_hour;
volatile u8 USB_min;
互换,那么USB_min也会为0.

使用特权

评论回复
16
qqqlijie|  楼主 | 2015-4-2 14:00 | 只看该作者
hgjinwei 发表于 2015-4-1 22:13
u8 System_time[5]={0x31,0x32,':',0x30,0x30};
volatile u8 USB_hour;
volatile u8 USB_min;

有9楼的现象,怎么解释呢?

使用特权

评论回复
17
hgjinwei| | 2015-4-2 22:23 | 只看该作者
qqqlijie 发表于 2015-4-2 14:00
有9楼的现象,怎么解释呢?

程序变更后,编译器有可能重新分配了变量占用内存的空间,就有可能出现9楼的现象,可以查看一下map图。

不管怎样,sprintf输出绝对是存在字符串结束符的。

使用特权

评论回复
18
schspa| | 2015-4-13 15:06 | 只看该作者
你这很明显的越界了,u8 System_time[5]={0x31,0x32,':',0x30,0x30};就给5个字节长度,下边存的就是hour,越界就改掉了呀,%2d打印时不够2个的2个对齐,3个字符的话就会覆盖,不知道有没有/0的影响.

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

21

主题

138

帖子

1

粉丝