SDCC 是一个开源免费的 C编译器,且支持跨平台,是在 Linux 下开发嵌入式( 51单片机 )应用的得力工具。但是其只有命令行的方式,使用起来诸多不方便。于是做了一个前端( SDCC 需要自行另外安装),代码编辑体验比 Keil 好很多,支持 Linux、Windows 平台,支持 x86、mips64el( loongson 3A ) 架构。
对于一些坛友说的 SDCC 的兼容性问题,我想说只要注意以下几点,基本没啥问题。
(为了简洁,下面的例子只截取关键部分代码,完整的验证程序在附件的 demo 里)
1、位取反操作使用 "! "而不要使用"~"
- typedef unsigned char uint8;
- #define PRINT_BIT_INVERSE 0x11
- #define PRINT_BIT_NOT 0x22
- void uart1_irq() __interrupt 4
- {
- uint8 i;
-
- if (RI) {
- RI = 0;
- i = SBUF;
-
- if (PRINT_BIT_INVERSE == i) { //打印 00 01 或 01 01 结果是不确定的
- uart1_send(IT0);
- IT0 = ~IT0;
- uart1_send(IT0);
- }else if (PRINT_BIT_NOT == i) { //00 01 与 01 00 交替打印,结果与预期一致
- uart1_send(IT0);
- IT0 = !IT0;
- uart1_send(IT0);
- }
- }
复制代码
2、SDCC 内部数据使用小端存储,Keil 使用的是大端存储,所以访问大于1个字节以上的寄存器时需要分别赋值或读取
- void uart1_irq() __interrupt 4
- {
- uint8 i;
-
- if (RI) {
- RI = 0;
- i = SBUF;
- uart1_send(i); //先打印执行的指令
-
- //此时 PWM1_CNTR 设置值如下
- //PWM1_CNTRH = 0x12;
- //PWM1_CNTRL = 0x34;
- if (PRINT_PWM1_CNTR == i) { //打印 PWM1_CNTR,打印 34 12
- uart1_send(PWM1_CNTR >> 8);
- uart1_send(PWM1_CNTR);
- }else if (PRINT_PWM1_CNTR_DIV == i) { //分别打印 PWM1_CNTR,打印 12 34
- uart1_send(PWM1_CNTRH);
- uart1_send(PWM1_CNTRL);
- }else if (PRINT_BGV == i) { //打印参考电压,打印 A4 04
- uart1_send(*BGV >> 8);
- uart1_send(*BGV);
- }else if (PRINT_BGV_DIV == i) { //分别打印参考电压, 打印 04 A4,0x04A4十进制为1188符合STC8H内部参考电压范围
- uart1_send(*BGVH);
- uart1_send(*BGVL);
- }
- }
- }
复制代码
3、中断服务声明或定义必须在main函数所在文件中可见才能正常工作
- //将中断服务移到 uart1_interrupt.c 文件
- //如果注释掉下面这个声明,串口1就不能正常收发
- void uart1_irq() __interrupt 4;
复制代码
4、char 类型默认为 unsigned char 而非 signed char
- <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;">//(编译前要将首选项中“char类型默认为有符号”选项取消勾选)</p>
- <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;">char test = 0; //声明为 char 或者 unsigned char 时,程序交替打印128个 11 和128个 ff,而不会打印 00</p>
- <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;">//signed char test = 0;//声明为 signed char 时,程序交替打印128个 11 与128个 00 ,而不会打印 ff</p><style type="text/css">p, li { white-space: pre-wrap; }</style>
- void main()
- {
- while (1) {
- WDT_CONTR |= 0x10; //清看门狗
-
- ++test;
- if (test < 0) {
- uart1_send(0x00);
- }else if (test >= 0x80) {
- uart1_send(0xFF);
- }else {
- uart1_send(0x11);
- }
-
- delay_ms(200);
- }
- }
复制代码 下载:
LitMill-v0.8.7z
(10.91 MB, 下载次数: 13)
|