sdcc+platformio开发51单片机
由于sdcc没有<INTRINS.H>,所以用中断实现流水灯的程序当中循环位移_crol_和_cror_只能内嵌汇编来写,但是不知道这样写为什么执行中断语句后,灯移了一位,下面就全亮了,没有做到循环移位的效果
没有实现流水灯,而是直接全亮
代码
主程序
#include <8052.h>
#include "Timer0.h" // STC-ISP对新系列单片机配置
#include "Key.h"
unsigned char key_number, led_mode;
void Timer0_Rountine(void) __interrupt (1);
void main() {
__asm
MOV A, #0XFE
MOV P2, A
__endasm;
Timer0Init();
while (1) {
key_number = Key();
if (key_number) {
// 控制led_mode只会按1, 0, 1, 0, … 变化
if (key_number == 1) {
led_mode++;
if (led_mode >= 2) led_mode = 0;
}
}
}
}
void Timer0_Rountine(void) __interrupt (1) {
static unsigned int t0_count;
TL0 = 0x18; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
t0_count++;
if (t0_count >= 500) {
t0_count = 0;
if (led_mode == 0) {
__asm
RL A
MOV P2,A
__endasm;
}
if (led_mode == 1) {
__asm
RR A
MOV P2, A
__endasm;
}
}
}
Timer0.c
#include <8052.h>
/*
* @brief 定时器0初始化,1毫秒@12.000MHz
* @param 无
* @retval 无
*/
void Timer0Init(void) //1毫秒@12MHz
{
//AUXR &= 0x7F; //定时器时钟12T模式,新系列有AUXR寄存器,本次不设置
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x18; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
TF0 = 0;
TR0 = 1;
ET0 = 1;
EA = 1;
PT0 = 0;
}
Key.c
#include <8052.h>
#include "Delay.h"
/*
* @brief 获取独立按键键码
* @param 无
* @retval 按下按键的键码,范围0 ~ 4,无按键按下时返回值为0
*/
unsigned char Key() {
unsigned char key_number = 0;
if (P3_1 == 0) {
Delay(20);
while (P3_1 == 0) {}
Delay(20);
key_number = 1;
}
if (P3_0 == 0) {
Delay(20);
while (P3_0 == 0) {}
Delay(20);
key_number = 2;
}
if (P3_2 == 0) {
Delay(20);
while (P3_2 == 0) {}
Delay(20);
key_number = 3;
}
if (P3_3 == 0) {
Delay(20);
while (P3_3 == 0) {}
Delay(20);
key_number = 4;
}
return key_number;
}
Delay.c
void Delay(unsigned int xms) {
unsigned char i, j;
while (xms--) {
i = 2;
j = 239;
do {
while (--j) {}
} while (--i);
}
}
运行结果就是sdcc编译通过没有报错但是LED灯全亮
Processing STC89C52RC (platform: intel_mcs51; board: STC89C52RC)
----------------------------------------------------------------------------------------------------------------------------------------------Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/intel_mcs51/STC89C52RC.html
PLATFORM: Intel MCS-51 (8051) (2.1.0) > Generic STC89C52RC
HARDWARE: STC89C52RC 11MHz, 512B RAM, 8KB Flash
PACKAGES:
- toolchain-sdcc @ 1.40200.0 (4.2.0)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 0 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
Compiling .pio\build\STC89C52RC\src\main.rel
Compiling .pio\build\STC89C52RC\src\test.rel
Linking .pio\build\STC89C52RC\firmware.hex
Checking size .pio\build\STC89C52RC\firmware.hex
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
Flash: [ ] 4.3% (used 351 bytes from 8192 bytes)
======================================================== [SUCCESS] Took 0.80 seconds ========================================================
* Terminal will be reused by tasks, press any key to close it.
如果用Keil可以用<INTRINS.H>的话还是可以做出来的,但是sdcc没有不进位的循环位移,而且要求用中断非数组的方法实现,就不懂怎么把这两个函数转换成汇编的形式可以在sdcc下实现一样的功能,主要是这一段:
if (led_mode == 0) {
__asm
RL A
MOV P2,A
__endasm;
}
if (led_mode == 1) {
__asm
RR A
MOV P2, A
__endasm;
}
}