屏幕终于显示了…

本身LCD1602挺好搞定的, 但就是太费IO口了. 于是用一块595做串口转并口. 设计电路+焊板子一共用了半节数据结构课+一中午. 终于焊好了, 准备试试效果. 结果…和想象的一样, 绝对不会让我一次成功.

然后呢,用万用表测测是不是板子没焊好吧,没有呀,都焊的牢牢实实的,把代码中乱七八糟的东西删了,只输出8位数字到595,用万用表也测不出电压,所有引脚都是0。怒了,一天都没过好!第二天,重整心情,还以为是那块595有问题(唉芯片一般不坏的,怎么就脑子抽了)然后用最后一块595又做了一块板子,竟然还是一样的效果!唉,无语了,突然想到,做个led板专门用来测试电平吧,做好之后竟然发现,两个板子都没坏,595输出的很好!最后终于发现,原来又是代码中的bug,原来串行输出应该MSB优先T^T唉,白费了两天功夫。不过做了个LED测试板还挺有用呢

怎么都今天了我还没发出这篇文章 前几天就写了一直在草稿箱里

image_1bl057qaa12411tafrfdjaj2f89.png-272.2kB

image_1bl0581l565iv9l2ji7q1jkvm.png-733.7kB

image_1bl058eg41cq2mcp11oeeoo6bo13.png-756.2kB

image_1bl058llt13a8p9ed521bi14bm1g.png-732.7kB

延时函数的一个BUG

延时函数的一个BUG

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void Delay_us (unsigned char time_us)
{
TR2 = 0; // Stop timer
TF2H = 0; // Clear timer overflow flag
TMR2 = -( (unsigned int)(SYSCLK * time_us / 1000000) );
TR2 = 1; // Start timer
while (!TF2H); // Wait till timer overflow occurs
TR2 = 0; // Stop timer
}

void Delay_ms (unsigned char time_ms)
{
unsigned char i;

while(time_ms--)
for(i = 0; i< 10; i++) // 10 * 100 microsecond delay
Delay_us(100);
}

先贴代码

这是silicon lab里自带的例子(其实不是, 本身第五行是这样写的

1
TMR2  = -( (UINT)(SYSCLK/1000000) * (UINT)(time_us) );

不论现在两种方法怎么写都有BUG.

先看silicon原版的吧, SYSCLK为24500000时除以1000000等于24.5, 转为整数, 近似成24, 这样还好, 差别不大.

假如没有开那么高的频率呢, 一般情况下, 我测试时用默认的8分频, 也就是SYSCLK = 12000000 / 8 = 1500000= 1.5MHZ (用F340说吧, 比较明显)

SYSCLK / 1000000 = 1 < 1.5

一下子比1.5小了三分之一

导致我每次演示都会快那么三分之一.

然后我就把代码改成了上面贴的那样.

没想到, 当时以为改对了的, 还是有BUG.

当时的想法是, 既然除以1000000之后把小数部分消去了, 那就先乘上time_us(当时也意识到了, 这样会比之前慢一些, 因为SYSCLK / 1000000会在编译时优化求值, 而先做乘法, 再做除法的话两个工作都会在运行时进行)

如果当时的想法能向前再走一步的话就会找到这个BUG了. 既然要在运行时进行, 那么SYSCLK>32768, 会被认为是为signed int, 然后乘以time_us, time_us是unsigned char类型. 所以提升成signed int, 可是在Delay_ms函数中调用的是Delay_us(100), 24500000 * 100 = 2’450’000’000而232 / 2 – 1 = 2’147’483’647, 比2’450’000’000要小!, signed int的最大值竟然比2’450’000’000还小…之后的事情大家知道了吧, 2’450’000’000会被截断成一个负数!(对, 就是负数…)

image_1bl05485217g51fci1kl2i1g19809.png-74.2kB

原谅我才疏学浅, 这是第一次遇见超整数上限的事情(貌似原来写PSP程序的时候也遇见过一次, 取随机数超过signed int上限, psp平台的随机数最大是SIGNED_INT_MAX, 再进行加法的话就变成负的了)

一定记住教训!

Proudly powered by Hexo and Theme by Hacker
© 2021 wastecat