IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发工具 -> 51学习(2):vscode+ Embedded IDE开发环境搭建 -> 正文阅读

[开发工具]51学习(2):vscode+ Embedded IDE开发环境搭建

前言

platformIO虽然可以用于编译8051,但是修改头文件包含路径,以及编译器选项都较为麻烦。Embedded IDE界面类似Visual Studio,设置较为方便。

环境

  • 单片机:普中-STC89C516RD+

正文

一,安装Embedded IDE和SDCC编译器

platformIO使用的也是SDCC编译器,但是Embedded IDE需要自己下载安装SDCC编译器

  1. 下载安装SDCC编译器:
    sdcc官方网页
    sdcc-4.1.0-x64-setup.exe
  2. Embedded IDE 配置 sdcc 编译器路径
    点击下图中的构建配置即可配置。
    Snipaste_2022-02-07_17-19-52.png

二,单片机头文件

首先,如果是STC-ISP系列的单片机可以在下图下载软件界面的头文件栏获取对应的头文件。
Snipaste_2022-02-07_17-23-43.png

这个头文件 SDCC无法直接使用。
这是因为SDCC 使用了一些非标准的关键字

头文件转换方法一

使用附件一:main.c代码进行转换,转换的时候注意待转换文件中不得包含特别长的注释(也可能出现其他的问题,这个是C代码问题,有兴趣可以重写)。

//转换前
sfr P0   = 0x80;
sbit P00 = P0^0;
//转换后
SFR(P0, 0x80);
SBIT(P00, 0x80, 0);

转换后就可以直接使用了。

头文件转换方法二(推荐)

使用perl脚本

这个脚本是sdcc源码文件中自带的,用于keil头文件转sdcc头文件。
但是实际使用时,我又做了一些修改,修改后的脚本见附件2:keil2sdcc.pl
运行脚本需要安装perl运行环境:官方 perl strawberry版本下载地址

解决vscode 不能识别 sdcc 扩展语法问题

最后为了vscode能够正确的标记表示语法,还需要加上下面的代码

#ifndef __SDCC
#include <lint.h>
#error "This header file must be used for SDCC compiler !"
#endif
#include <compiler.h>

lint.h是sdcc自带的一个头文件,里面是sdcc自定义的关键字的空定义,可以用来避免vscode语法检查报错。
具体实现详见附件3:stc89xx.h

三,附件

1,main.c

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main(int argc, char* args[])
{
    string filename = "STC89xx.h";
    ifstream file_in(filename.c_str());

    string s;
    string previous_addr;
    while( getline(file_in,s) )
    {
        if(s[0] == '/' || s[0] == '#')
            cout << s << endl;
        else if(s.length() > 4)
        {
            string::size_type type_end = s.find_first_of(' ');
            string type = s.substr(0, type_end);

            string::size_type name_begin = s.find_first_not_of(' ', type_end);
            string::size_type name_end = s.find_first_of(' ', name_begin);
            string name = s.substr(name_begin, name_end - name_begin);

            string::size_type addr_begin = s.find_first_not_of(" =", name_end);
            string::size_type addr_end = s.find_first_of(" ;", addr_begin);
            string addr = s.substr(addr_begin, addr_end - addr_begin);

            string comment;
            bool haveComment = true;
            if(addr_end == s.length() - 1)
            {
                haveComment = false;
            }

            if(haveComment)
            {
                string::size_type comment_begin = s.find_first_not_of("; ", addr_end);
                comment = s.substr(comment_begin);
            }

            if(type == "sfr")
            {
                cout << "SFR(" << name << ", "  << addr << ");";
                if(haveComment) cout << comment;
                cout << endl;
                previous_addr = addr;
            }
            else if(type == "sbit")
            {
                string bit_offset = addr.substr(addr.length()-1);

                cout << "SBIT(" << name << ", "  << previous_addr << ", " << bit_offset << ");";
                if(haveComment) cout << comment;
                cout << endl;
            }

        }
    }
    return 0;
}

2,keil2sdcc.pl (在sdcc原版上修改后)

#!/usr/bin/perl -w

# keil2sdcc.pl
# Scott Bronson
# 22 June 2003


# usage (UNIX):
#    perl keil2sdcc.pl < keil_header.h > sdcc_header.h
# or
#    perl keil2sdcc.pl keil_header.h > sdcc_header.h
#
# usage (Windows):
#    perl keil2sdcc.pl keil_header.h > sdcc_header.h
#
#
# keil_header.h and sdcc_header.h must not be the same file since
# most shells overwrite the output file before opening the input file.


# This script converts Keil-style header files to SDCC.  It tries to
# be pedantic so don't be surprised if you need to munge it a bit to
# get it to work.  On the other hand, it doesn't fully parse the C
# file (for obvious reasons).

# It takes the Keil header file either as an argument or on
# stdin and it produces the output on stdout.

# This script is inspired by keil2sdcc.pl by Bela Torok but a lot
# more pedantic.

use strict;
my %data;

while(<>) 
{
	s/\r//g;  	# remove DOS line endings if necessary

	# external register (kind of a weird format)
	#
	# in:  EXTERN xdata volatile BYTE GPIF_WAVE_DATA _AT_ 0xE400;
	# out: EXTERN xdata at 0xE400 volatile BYTE GPIF_WAVE_DATA;
	# $1: leading whitespace
	# $2: variable name
	# $3: variable location
	# $4: trailing comments, etc.

	if(/^(\s*)EXTERN\s*xdata\s*volatile\s*BYTE\s*(\w+(?:\s*\[\s*\d+\s*\])?)\s+_AT_\s*([^;]+);(.*)$/) {
		print "$1EXTERN xdata at $3 volatile BYTE $2;$4\n";
		next;
	}

	# sfr statement
	#
	# in:  sfr IOA = 0x80;
	# out: SFR(0x80, IOA);
	# $1: leading whitespace
	# $2: variable name
	# $3: variable location
	# $4: trailing comments, etc.

	if(/^(\s*)sfr\s*(\w+)\s*=\s*([^;]+);(.*)$/) {
		print "$1SFR($2, $3);$4\n";
		$data{-$2} = $3;
		next;
	}

	# sbit statement
	#
	# in:  sbit SEL = 0x86^0;
	# out: sbit (SEL, 0x86, 0);
	# $1: leading whitespace
	# $2: variable name
	# $3: variable location
	# $4: variable number
	# $5: trailing comments, etc.

	if(/^(\s*)sbit\s*(\w+)\s*=\s*(\w+)\s*\^\s*([^;]+);(.*)$/) {
		print "$1SBIT($2, $data{-$3}, $4);$5\n";
		next;
	}



	# entire line is a C++ comment, output it unchanged.
	if(/^(\s*)\/\/(.*)$/) {
		print "$1//$2\n";
		next;
	}

	# C comment, slurp lines until the close comment and output it unchanged.
	if(/^(\s*)\/\*(.*)$/) {
		my($ws,$cmt) = ($1,"$2\n");
		$cmt .= <> while $cmt !~ /\*\/\s*$/;
		$cmt =~ s/\r//g;
		print "$ws/*$cmt";
		next;
	}

	# preprocessor statement (whitespace followed by '#'), don't change
	if(/^(\s*)\#(.*)$/) {
		print "$1#$2\n";
		next;
	}

	# blank line, don't change
	if(/^(\s*)$/) {
		print "\n";
		next;
	}

	chomp;
	die "Unconvertable line: \"$_\"\n";
}


3,stc89xx.h (使用perl脚本转换后)

#ifndef __STC89C5xRC_RDP_H__
#define __STC89C5xRC_RDP_H__

#ifndef __SDCC
#include <lint.h>
#error "This header file must be used for SDCC compiler !"
#endif
#include <compiler.h>

typedef unsigned int u16;
typedef unsigned char u8;
/

/* The following is STC additional SFR */

/* sfr  AUXR  = 0x8e; */
/* sfr  AUXR1 = 0xa2; */
/* sfr  IPH   = 0xb7; */

SFR(P4, 0xe8);
SBIT(P46, 0xe8, 6);
SBIT(P45, 0xe8, 5);       //ISP下载需勾选"ALE脚用作P4.5口"
SBIT(P44, 0xe8, 4);
SBIT(P43, 0xe8, 3);
SBIT(P42, 0xe8, 2);
SBIT(P41, 0xe8, 1);
SBIT(P40, 0xe8, 0);

SFR(XICON, 0xc0);

SFR(WDT_CONTR, 0xe1);

SFR(ISP_DATA, 0xe2);
SFR(ISP_ADDRH, 0xe3);
SFR(ISP_ADDRL, 0xe4);
SFR(ISP_CMD, 0xe5);
SFR(ISP_TRIG, 0xe6);
SFR(ISP_CONTR, 0xe7);

/* Above is STC additional SFR */

/*  BYTE Registers  */
SFR(P0, 0x80);
SBIT(P00, 0x80, 0);
SBIT(P01, 0x80, 1);
SBIT(P02, 0x80, 2);
SBIT(P03, 0x80, 3);
SBIT(P04, 0x80, 4);
SBIT(P05, 0x80, 5);
SBIT(P06, 0x80, 6);
SBIT(P07, 0x80, 7);
SFR(P1, 0x90);
SBIT(P10, 0x90, 0);
SBIT(P11, 0x90, 1);
SBIT(P12, 0x90, 2);
SBIT(P13, 0x90, 3);
SBIT(P14, 0x90, 4);
SBIT(P15, 0x90, 5);
SBIT(P16, 0x90, 6);
SBIT(P17, 0x90, 7);
SFR(P2, 0xA0);
SBIT(P20, 0xA0, 0);
SBIT(P21, 0xA0, 1);
SBIT(P22, 0xA0, 2);
SBIT(P23, 0xA0, 3);
SBIT(P24, 0xA0, 4);
SBIT(P25, 0xA0, 5);
SBIT(P26, 0xA0, 6);
SBIT(P27, 0xA0, 7);
SFR(P3, 0xB0);
SBIT(P30, 0xB0, 0);
SBIT(P31, 0xB0, 1);
SBIT(P32, 0xB0, 2);
SBIT(P33, 0xB0, 3);
SBIT(P34, 0xB0, 4);
SBIT(P35, 0xB0, 5);
SBIT(P36, 0xB0, 6);
SBIT(P37, 0xB0, 7);
SFR(PSW, 0xD0);
SFR(ACC, 0xE0);
SFR(B, 0xF0);
SFR(SP, 0x81);
SFR(DPL, 0x82);
SFR(DPH, 0x83);
SFR(PCON, 0x87);
SFR(TCON, 0x88);
SFR(TMOD, 0x89);
SFR(TL0, 0x8A);
SFR(TL1, 0x8B);
SFR(TH0, 0x8C);
SFR(TH1, 0x8D);
SFR(IE, 0xA8);
SFR(IP, 0xB8);
SFR(SCON, 0x98);
SFR(SBUF, 0x99);

/*  80C51Fx/Rx Extensions  */
SFR(AUXR, 0x8E);
SFR(AUXR1, 0xA2);
SFR(SADDR, 0xA9);
SFR(IPH, 0xB7);
SFR(SADEN, 0xB9);
SFR(T2CON, 0xC8);
SFR(T2MOD, 0xC9);
SFR(RCAP2L, 0xCA);
SFR(RCAP2H, 0xCB);
SFR(TL2, 0xCC);
SFR(TH2, 0xCD);

/*  BIT Registers  */
/*  PSW   */
SBIT(CY, 0xD0, 7);
SBIT(AC, 0xD0, 6);
SBIT(F0, 0xD0, 5);
SBIT(RS1, 0xD0, 4);
SBIT(RS0, 0xD0, 3);
SBIT(OV, 0xD0, 2);
SBIT(F1, 0xD0, 1);
SBIT(P, 0xD0, 0);

/*  TCON  */
SBIT(TF1, 0x88, 7);
SBIT(TR1, 0x88, 6);
SBIT(TF0, 0x88, 5);
SBIT(TR0, 0x88, 4);
SBIT(IE1, 0x88, 3);
SBIT(IT1, 0x88, 2);
SBIT(IE0, 0x88, 1);
SBIT(IT0, 0x88, 0);

/*  IE   */
SBIT(EA, 0xA8, 7);
SBIT(EC, 0xA8, 6);
SBIT(ET2, 0xA8, 5);
SBIT(ES, 0xA8, 4);
SBIT(ET1, 0xA8, 3);
SBIT(EX1, 0xA8, 2);
SBIT(ET0, 0xA8, 1);
SBIT(EX0, 0xA8, 0);

/*  IP   */ 
/*  sbit PPC  = IP^6;*/
SBIT(PT2, 0xB8, 5);
SBIT(PS, 0xB8, 4);
SBIT(PT1, 0xB8, 3);
SBIT(PX1, 0xB8, 2);
SBIT(PT0, 0xB8, 1);
SBIT(PX0, 0xB8, 0);

/*  P3  */
SBIT(RD, 0xB0, 7);
SBIT(WR, 0xB0, 6);
SBIT(T1, 0xB0, 5);
SBIT(T0, 0xB0, 4);
SBIT(INT1, 0xB0, 3);
SBIT(INT0, 0xB0, 2);
SBIT(TXD, 0xB0, 1);
SBIT(RXD, 0xB0, 0);

/*  SCON  */
SBIT(SM0, 0x98, 7); // alternatively "FE"
SBIT(FE, 0x98, 7);
SBIT(SM1, 0x98, 6);
SBIT(SM2, 0x98, 5);
SBIT(REN, 0x98, 4);
SBIT(TB8, 0x98, 3);
SBIT(RB8, 0x98, 2);
SBIT(TI, 0x98, 1);
SBIT(RI, 0x98, 0);

SBIT(T2EX, 0x90, 1);
SBIT(T2, 0x90, 0);

/*  T2CON  */
SBIT(TF2, 0xC8, 7);
SBIT(EXF2, 0xC8, 6);
SBIT(RCLK, 0xC8, 5);
SBIT(TCLK, 0xC8, 4);
SBIT(EXEN2, 0xC8, 3);
SBIT(TR2, 0xC8, 2);
SBIT(C_T2, 0xC8, 1);
SBIT(CP_RL2, 0xC8, 0);

/

#endif


参考文献

  1. SDCC编译器 + VSCode开发 8位微控制器
  2. Embedded IDE 文档
  3. 突然要用 STC 写个东西,但是发现没有SDCC头文件,写个工具
  4. sdcc官方手册
  开发工具 最新文章
Postman接口测试之Mock快速入门
ASCII码空格替换查表_最全ASCII码对照表0-2
如何使用 ssh 建立 socks 代理
Typora配合PicGo阿里云图床配置
SoapUI、Jmeter、Postman三种接口测试工具的
github用相对路径显示图片_GitHub 中 readm
Windows编译g2o及其g2o viewer
解决jupyter notebook无法连接/ jupyter连接
Git恢复到之前版本
VScode常用快捷键
上一篇文章      下一篇文章      查看所有文章
加:2022-02-26 11:50:46  更:2022-02-26 11:51:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:38:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码