VSCode PlatformIO开发STC单片机注意事项
Posted perseverance52
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VSCode PlatformIO开发STC单片机注意事项相关的知识,希望对你有一定的参考价值。
VSCode PlatformIO开发STC单片机注意事项
首先需要注意代码的语法
- 附上本论坛一位网友总结的笔记
其实开源的SDCC+code blocks也不错的。
SDCC语法与keil C有一点点不同,记录如下:
* 1 sbit *
// keil c :
sbit LED1=P1^3 ;
// SDCC
#define LED1 P1_3
* 2 中断 *
keil c 的中断
void SerialComm(void ) interrupt 4 ;
sdcc 的中断
void SerialComm(void) __interrupt 4;
* 3 _nop()_ *
sdcc 没有 _nop()_ , 可用如下自定义宏代替:
#define _nop()_ __asm NOP __endasm
头文件包含
lint.h
里面定义了有关硬件相关寄存器的宏,没有包含的话,在直接使用单片机特殊功能寄存器的话都会出现
波浪号
,是一个很重要的头文件,在单片机的时候,务必首先将此头文件包含进去。
#ifndef _LINT_H
#define _LINT_H
#if !defined(__SDCC_mcs51)
#define __data
#define __near
#define __idata
#define __xdata
#define __far
#define __pdata
#define __code
#define __bit bool
#define __sfr volatile unsigned char
#define __sbit volatile bool
#define __critical
#define __at(x) /* use "__at (0xab)" instead of "__at 0xab" */
#define __using(x)
#define __interrupt(x)
#define __naked
#define data
#define near
#define idata
#define xdata
#define far
#define pdata
#define code
#define bit bool
#define sfr volatile unsigned char
#define sbit volatile bool
#define critical
#define at(x)
#define using(x)
#define interrupt(x)
#define naked
/* The tool Splint is available at http://www.splint.org
Other tools might also be used for statically checking c-sources.
Traditionally they could have "lint" in their name.
*/
#if defined(S_SPLINT_S)
/* Behaviour of splint can be modified by special comments.
Some examples are shown below.
Note 1: most probably you'll want to copy this complete file into
your source directory, adapt the settings to your needs and use
#include "lint.h" as the first include in your source file(s).
You should then be able to either directly compile your file
or to run a check with splint over it without other changes.
Note 2: you need brackets around arguments for special
keywords, so f.e. it's "interrupt (1)" instead of "interrupt 1".
*/
/*@ +charindex @*/
#endif
#endif
#endif
stdio.h
头文件在这里插入代码片
此头文件里面定义了有一个比较常用的
printf
函数,关于此头文件的内容比较多,就比贴出内容来了。
stdint.h
头文件
此头文件里面定义了数据类型的简写。
#ifndef _STDINT_H
#define _STDINT_H
#include <crtdefs.h>
#define __need_wint_t
#define __need_wchar_t
#include <stddef.h>
/* 7.18.1.1 Exact-width integer types */
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned uint32_t;
__MINGW_EXTENSION typedef long long int64_t;
__MINGW_EXTENSION typedef unsigned long long uint64_t;
/* 7.18.1.2 Minimum-width integer types */
typedef signed char int_least8_t;
typedef unsigned char uint_least8_t;
typedef short int_least16_t;
typedef unsigned short uint_least16_t;
typedef int int_least32_t;
typedef unsigned uint_least32_t;
__MINGW_EXTENSION typedef long long int_least64_t;
__MINGW_EXTENSION typedef unsigned long long uint_least64_t;
/* 7.18.1.3 Fastest minimum-width integer types
* Not actually guaranteed to be fastest for all purposes
* Here we use the exact-width types for 8 and 16-bit ints.
*/
typedef signed char int_fast8_t;
typedef unsigned char uint_fast8_t;
typedef short int_fast16_t;
typedef unsigned short uint_fast16_t;
typedef int int_fast32_t;
typedef unsigned int uint_fast32_t;
__MINGW_EXTENSION typedef long long int_fast64_t;
__MINGW_EXTENSION typedef unsigned long long uint_fast64_t;
/* 7.18.1.5 Greatest-width integer types */
__MINGW_EXTENSION typedef long long intmax_t;
__MINGW_EXTENSION typedef unsigned long long uintmax_t;
/* 7.18.2 Limits of specified-width integer types */
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) || \\
defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
/* 7.18.2.1 Limits of exact-width integer types */
#define INT8_MIN (-128)
#define INT16_MIN (-32768)
#define INT32_MIN (-2147483647 - 1)
#define INT64_MIN (-9223372036854775807LL - 1)
#define INT8_MAX 127
#define INT16_MAX 32767
#define INT32_MAX 2147483647
#define INT64_MAX 9223372036854775807LL
#define UINT8_MAX 255
#define UINT16_MAX 65535
#define UINT32_MAX 0xffffffffU /* 4294967295U */
#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */
/* 7.18.2.2 Limits of minimum-width integer types */
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
/* 7.18.2.3 Limits of fastest minimum-width integer types */
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
/* 7.18.2.4 Limits of integer types capable of holding
object pointers */
#ifdef _WIN64
#define INTPTR_MIN INT64_MIN
#define INTPTR_MAX INT64_MAX
#define UINTPTR_MAX UINT64_MAX
#else
#define INTPTR_MIN INT32_MIN
#define INTPTR_MAX INT32_MAX
#define UINTPTR_MAX UINT32_MAX
#endif
/* 7.18.2.5 Limits of greatest-width integer types */
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX
/* 7.18.3 Limits of other integer types */
#ifdef _WIN64
#define PTRDIFF_MIN INT64_MIN
#define PTRDIFF_MAX INT64_MAX
#else
#define PTRDIFF_MIN INT32_MIN
#define PTRDIFF_MAX INT32_MAX
#endif
#define SIG_ATOMIC_MIN INT32_MIN
#define SIG_ATOMIC_MAX INT32_MAX
#ifndef SIZE_MAX
#ifdef _WIN64
#define SIZE_MAX UINT64_MAX
#else
#define SIZE_MAX UINT32_MAX
#endif
#endif
#ifndef WCHAR_MIN /* also in wchar.h */
#define WCHAR_MIN 0U
#define WCHAR_MAX 0xffffU
#endif
/*
* wint_t is unsigned short for compatibility with MS runtime
*/
#define WINT_MIN 0U
#define WINT_MAX 0xffffU
#endif /* !defined ( __cplusplus) || defined __STDC_LIMIT_MACROS */
/* 7.18.4 Macros for integer constants */
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) || \\
defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
/* 7.18.4.1 Macros for minimum-width integer constants
Accoding to Douglas Gwyn <gwyn@arl.mil>:
"This spec was changed in ISO/IEC 9899:1999 TC1; in ISO/IEC
9899:1999 as initially published, the expansion was required
to be an integer constant of precisely matching type, which
is impossible to accomplish for the shorter types on most
platforms, because C99 provides no standard way to designate
an integer constant with width less than that of type int.
TC1 changed this to require just an integer constant
*expression* with *promoted* type."
The trick used here is from Clive D W Feather.
*/
#define INT8_C(val) (INT_LEAST8_MAX-INT_LEAST8_MAX+(val))
#define INT16_C(val) (INT_LEAST16_MAX-INT_LEAST16_MAX+(val))
#define INT32_C(val) (INT_LEAST32_MAX-INT_LEAST32_MAX+(val))
/* The 'trick' doesn't work in C89 for long long because, without
suffix, (val) will be evaluated as int, not intmax_t */
#define INT64_C(val) val##LL
#define UINT8_C(val) (val)
#define UINT16_C(val) (val)
#define UINT32_C(val) (val##U)
#define UINT64_C(val) val##ULL
/* 7.18.4.2 Macros for greatest-width integer constants */
#define INTMAX_C(val) val##LL
#define UINTMAX_C(val) val##ULL
#endif /* !defined ( __cplusplus) || defined __STDC_CONSTANT_MACROS */
#endif /* _STDINT_H */
以上头文件的加载的话根据个人使用按需加载,当然还有其他的头文件,可以自行到编译器所在目录下查看翻阅和了解。
我的VSCode PlatformIO SDCC编译器文件位置:
C:\\Users\\Administrator\\.platformio\\packages\\toolchain-sdcc\\include
独立安装的SDCC编译
- SDCC下载的地方:https://sourceforge.net/projects/sdcc/files/
- 独立下载和安装SDCC4.1.0编译器(X64位的):https://jaist.dl.sourceforge.net/project/sdcc/sdcc-win64/4.1.0/sdcc-4.1.0-x64-setup.exe
例如我安装的独立sdcc编译器路径:
D:\\Program Files\\SDCC\\include\\mcs51
VSCode PlatformIO调用独立安装的的SDCC编译器进行编译方法
- 在工程项目下的
c_cpp_properties.json
文件内添加如下语句:
// "compilerPath": "C:/Users/Administrator/.platformio/packages/toolchain-sdcc/bin/sdcc.exe",//这是默认使用平台提供的SDCC编译器位置
"compilerPath":"D:/Program Files/SDCC/bin/sdcc.exe",//添加此独立安装的sdcc编译器位置
- VSCode PlatformIO调用独立的SDCC编译工具进行编译
目前使用SDCC来开发STC单片机的人群不多,有许多暗坑,这里不对新手鼓励使用,比起Keil软件,这个工具毕竟是开源免费的编译器,对于个人和企业的话,可以免费使用。
目前发现的暗坑,在使用StC15开发的时候,想通过虚拟串口打印数据,发现编译后上传都没有问题,但是打印的信息是乱码,同样的代码在Keil里面编译上传没有问题,打印OK。
在VSCode PlatformIO平台使用SDCC编译的文件,虚拟串口就是打印的是乱码,刚开始我还以为使用VSCode PlatformIO是
stcgal
工具进行上传所导致的问题,后面我将编译生成的Hex文件使用STC-ISP工具进行单独烧录,也是不行。目前还没找到解决办法。
- 虚拟串口打印主要涉及的就是一个位函数
//========================================================================
// 函数: void BitTime(void)
// 描述: 位时间函数。
//========================================================================
void BitTime(void)
u16 i;
i = (16 * 104) / 13 - 1; //根据主时钟来计算位时间16
while (--i)
;
以上是关于VSCode PlatformIO开发STC单片机注意事项的主要内容,如果未能解决你的问题,请参考以下文章
STC单片机基于VSCode PlatformIO开发STC15W408AS软串口示例程序
VSCode PlatformIO开发STC单片机头文件和常用外设驱动头文件获取方式