PIC单片机的一些问题

  • error 1347

can't find 0x16 words (0x16 withtotal) for psect "text9" in class "CODE" (largest unused contiguous range 0x12)

解决方案:

Article URL

Microchip Lightning Support

简要说明:

你遇到了编译器的优化极限。这个时候需要把编译器的优化级别调整一下,位置在:

Project Properties -> XC8 global options -> XC8 compiler -> Optimizations categories = Optimizations

对我而言,从o0->o2,问题解决。

另外,你可能需要将函数处理为可重入的,意思就是不同的中断级别以及主线程各自有独立的栈。

你可能需要修改堆栈的大小,为此可能需要修改编译器c的类别,由c99->c90。

  • error can't mix prototyped and non-prototyped arguments

偶然看到招聘广告上看到有公司在招对C90,或者C99有了解的工程师。

很大的可能性,就是他们遭遇了类似的编译错误。因为这个问题在C99 - C90两种编译模式切换时才会发生。

解决这类问题没有必要对C标准有多么深入的理解。

解决方案:你可能遗留了重要的头文件包含,比如size_t的定义("string.h"),或者uint8_t的定义(" stdint.h")

补上即可。这是编译器输出没有那么精确导致的。

  • 关于手工进行adc采样

对于单片机,要特别注意采样间隔。这个采样间隔不仅仅是mcc提示你的采样间隔。你还需要考虑到单片机本身的运算极限。

MHz级别的单片机,对应uS的间隔,它的运算速度与人工的速度相似,它此时仅能完成有限条数的指令。要特别留神,你只能依据自动计数的定时器,你绝不可以通过中断计数来记录时间间隔。

  • 内存受限的编程环境,必知必会

首先你需要在代码中使用<stdint.h>

要非常熟悉 uint8_t int16_t这类变量。以及INT16_MAX 这类UINT16_MAX常量。

注意float可能为24bits或者32 bits.知晓它们的有效位数。

知道编译器double 和float的位宽是可以定制的。并且不同的位宽,相关的数学库的尺寸也不一致。

注意你的堆栈配置:参见下节:

  • 函数自动复制与堆栈配置

Home - Developer Help

这是一个很神奇的概念,我从未在其他的编译环境中看到过。

PIC单片机首先为了保证执行的过程不会因为堆栈溢出造成运行时错误,它把栈中出现的变量,固定到了data ram的确定位置,它的后果有两个:

  1. 它无法支持函数迭代。

  1. 出现了函数重入的问题。

为了解决这个问题,部分解决这个问题,PIC引入了函数复制的概念,凡是可能会同步运行的函数,都会额外复制一份。另外,为了避免在中断函数中出现同一个函数重入,PIC引入了三个独立的堆栈——主线程堆栈,低优先级堆栈和高优先级堆栈。。。

这就是那个警告的由来:

non-reentrant function “_foo” appears in multiple call graphs and has been duplicated by the compiler

为了避免出现因此引发的内存暴增问题,建议这样处理:

将堆栈模式改为hybrid

但是这样做会有风险——你的程序可能以为堆栈溢出跑飞。

它的实际效果:

stack = hybrid

stack=reentrant,如果是compile模式内存会爆掉.

PIC单片机怀疑在宇航,军品这类场合用过。默认的堆栈模式,不涉及动态内存分配。基本上不可能有运行时故障。

  • 为什么程序又卡死了?

嵌入式单片机,未引入分时操作系统之前,要注意,一旦你卡在中断里出不来,整个程序的运行会失去响应——这是很显然的事情,因为中断优先级高,主线程将无法得到运行的机会。

在程序卡死的时候,不要慌张,逐个扫描各个重要的分支跳转和循环语句,看看是否会卡死。

  • TTL电平usb->uart乱码的原因及处置策略

TTL电平的 USB->UART有时候会出现乱码,这大概率不是设备出现了故障,而是因为收发两侧,时钟频率和波特率不匹配造成的,比如,看这款芯片:

编辑

在采用64MHz的时候,波特率设置为115200波特率,会出现-3.55%的偏差。这个偏差如果不校准,仅仅使用Tx,Rx,Gnd异步盲发会偏得越来越厉害。

解决方案是什么呢?

1.软件上,选择特定波特率

可以选择那些理论上不可能有偏差的特殊波特率:比如,上图给出的64M晶振下,10417的波特率,是准的,64M可以被10417波特率下的单字节发送所需时间整除。(有时候,你发现公司的既有产品出现了一个很特别的波特率:1200, 38400差不多就是这个缘故。)

2.硬件上,选择特定振荡器

选择与特定波特率匹配的外部振荡器,来实现更精确的波特率输出。现代的代码生成器,有些会提供波特率的时钟误差验算,误差在0.01%的波特率已经可以启用异步收发大段数据了。

3.软件或者硬件:引入握手

握手有两种,硬握手和软握手。硬握手,单向传输需要额外的两根握手线;对于软握手,整个传输过程只需要三根线——TX,RX,GND

4.软件发送延时:最笨的方法

延时发送,在一次发送完即将产生错位的波形时,就需要停止下来,延时后再次发送。注意,一个字符的发送至少需要1起始位+8数据位+1停止位 = 10个bit.则如果对于3.55%的偏差,发送完一个字符,偏差就会增加至35.5%,基本上,这种模式,只能连续发送两个字符。第三个字符发送时必然会出错。

  • 复数运算

单片机环境,复数类型公式的验算可能会受限,将复数运算转换为标量运算很容易出错。我所使用的芯片,支持复数运算的xc8 v2.0更新的地方很多,如果是新项目,可以大胆尝试。

MPLAB® XC8 v2.0 Updates - Developer Help

PIC github上发布了一个使用自定义结构,实现复数运算的例程:Lab Exercise 15: Arrays of Structures - Developer Help

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

子正

thanks, bro...

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值