[15单片机] STC15F104W开发入门及模拟串口程序
STC15F104W开发入门及模拟串口程序
Saturday, 31. March 2018 09:42AM - beautifulzzzz

前言
最近找到一款51内核的SOP8封装的8脚单片机STC15F10x与大家分享!

1、基本介绍
下面是其一个典型应用——红外收发器实现:

是不是觉得麻雀虽小,五脏俱全呀,再看一下其架构图:


下面是其部分型号的外设列表和采购价格图(需要特别注意的是下面几款都是不带串口、CCP、PCA、PWM、AD的!因此,如果你想要用串口,就需要采用模拟的方法实现了。不过,好在宏晶官网提供了DEMO。):


2、DEMO&烧写
STC15和之前烧写STC51单片机一样,需要用STC-ISP,通过USB转TTL(RX接芯片的P31,TX接芯片的P30),选择好芯片等信息,点击下载,之后上电...
从官网下载最新的STC-ISP工具:stc-isp-15xx-v6.86L,务必要下载完全版!!!

在该工具的后面的范例程序中可以找到各种DEMO的C语言和汇编双版本.

3、编程
在STC-TOOL.pdf的第13章 编译器(汇编器)/ISP编程器(烧录)/仿真器说明中,介绍了用keil可以开发。由于STC15单片机型号较新,keil中目标单片机还没有,可以用Intel 80/87C58作为目标单片机。
此外,可以在STC官网下载打包好的驱动和DEMO:STC15系列库函数与例程测试版V1.0,2014-5-29

4、STC15F104W半双工串口DEMO
/************* 功能说明 **************
使用STC15系列的Timer2做的模拟串口. P3.0接收, P3.1发送, 半双工.
假定测试芯片的工作频率为11059200HZ. 时钟为5.5296MHZ ~ 35MHZ.
波特率高,则时钟也要选高, 优先使用 22.1184MHZ, 11.0592MHZ.
测试方法: 上位机发送数据, MCU收到数据后原样返回.
串口固定设置: 1位起始位, 8位数据位, 1位停止位, 波特率在范围如下.
1200 ~ 115200 bps @ 33.1776MHZ
600 ~ 115200 bps @ 22.1184MHZ
600 ~ 76800 bps @ 18.4320MHZ
300 ~ 57600 bps @ 11.0592MHZ
150 ~ 19200 bps @ 5.5296MHZ
******************************************/
#include <reg52.h>
#define MAIN_Fosc 11059200UL //定义主时钟
#define UART3_Baudrate 9600UL //定义波特率
#define RX_Lenth 32 //接收长度
#define UART3_BitTime (MAIN_Fosc / UART3_Baudrate)
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
sfr IE2 = 0xAF;
sfr AUXR = 0x8E;
sfr INT_CLKO = 0x8F;
sfr T2H = 0xD6;
sfr T2L = 0xD7;
sfr P1M1 = 0x91; //PxM1.n,PxM0.n =00--->Standard, 01--->push-pull
sfr P1M0 = 0x92; // =10--->pure input, 11--->open drain
sfr P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sfr P3M1 = 0xB1;
sfr P3M0 = 0xB2;
sfr P4M1 = 0xB3;
sfr P4M0 = 0xB4;
sfr P5M1 = 0xC9;
sfr P5M0 = 0xCA;
sfr P6M1 = 0xCB;
sfr P6M0 = 0xCC;
sfr P7M1 = 0xE1;
sfr P7M0 = 0xE2;
u8 Tx3_read; //发送读指针
u8 Rx3_write; //接收写指针
u8 idata buf3[RX_Lenth]; //接收缓冲
u16 RxTimeOut;
bit B_RxOk; //接收结束标志
//===================== 模拟串口相关===========================
sbit P_RX3 = P3^0; //定义模拟串口接收IO
sbit P_TX3 = P3^1; //定义模拟串口发送IO
u8 Tx3_DAT; // 发送移位变量, 用户不可见
u8 Rx3_DAT; // 接收移位变量, 用户不可见
u8 Tx3_BitCnt; // 发送数据的位计数器, 用户不可见
u8 Rx3_BitCnt; // 接收数据的位计数器, 用户不可见
u8 Rx3_BUF; // 接收到的字节, 用户读取
u8 Tx3_BUF; // 要发送的字节, 用户写入
bit Rx3_Ring; // 正在接收标志, 低层程序使用, 用户程序不可见
bit Tx3_Ting; // 正在发送标志, 用户置1请求发送, 底层发送完成清0
bit RX3_End; // 接收到一个字节, 用户查询 并清0
//=============================================================
void UART_Init(void);
void main(void){
P0M0 = P0M1 = P1M0 = P1M1 = P2M0 = P2M1 = P3M0 = P3M1 = 0x00;
P4M0 = P4M1 = P5M0 = P5M1 = P6M0 = P6M1 = P7M0 = P7M1 = 0x00;
UART_Init(); //PCA初始化
EA = 1;
while (1){ //user's function
if (RX3_End){ // 检测是否收到一个字节
RX3_End = 0; // 清除标志
buf3[Rx3_write] = Rx3_BUF; // 写入缓冲
if(++Rx3_write >= RX_Lenth) Rx3_write = 0; // 指向下一个位置, 溢出检测
RxTimeOut = 1000; //装载超时时间
}
if(RxTimeOut != 0){ // 超时时间是否非0?
if(--RxTimeOut == 0){ // (超时时间 - 1) == 0?
B_RxOk = 1;
AUXR &= ~(1<<4); //Timer2 停止运行
INT_CLKO &= ~(1 << 6); //禁止INT4中断
T2H = (65536 - UART3_BitTime) / 256; //数据位
T2L = (65536 - UART3_BitTime) % 256; //数据位
AUXR |= (1<<4); //Timer2 开始运行
}
}
if(B_RxOk){ // 检测是否接收OK?
if (!Tx3_Ting){ // 检测是否发送空闲
if (Tx3_read != Rx3_write){ // 检测是否收到过字符
Tx3_BUF = buf3[Tx3_read]; // 从缓冲读一个字符发送
Tx3_Ting = 1; // 设置发送标志
if(++Tx3_read >= RX_Lenth) Tx3_read = 0; // 指向下一个位置, 溢出检测
}else{
B_RxOk = 0;
AUXR &= ~(1<<4); //Timer2 停止运行
INT_CLKO |= (1 << 6); //允许INT4中断
}
}
}
}
}
// 描述: UART初始化程序.
void UART_Init(void){
Tx3_read = 0;
Rx3_write = 0;
Tx3_Ting = 0;
Rx3_Ring = 0;
RX3_End = 0;
Tx3_BitCnt = 0;
RxTimeOut = 0;
B_RxOk = 0;
AUXR &= ~(1<<4); // Timer2 停止运行
T2H = (65536 - UART3_BitTime) / 256; // 数据位
T2L = (65536 - UART3_BitTime) % 256; // 数据位
INT_CLKO |= (1 << 6); // 允许INT4中断
IE2 |= (1<<2); // 允许Timer2中断
AUXR |= (1<<2); // 1T
}
// 描述: Timer2中断处理程序.
void timer2_int (void) interrupt 12{
if(Rx3_Ring){ //已收到起始位
if (--Rx3_BitCnt == 0){ //接收完一帧数据
Rx3_Ring = 0; //停止接收
Rx3_BUF = Rx3_DAT; //存储数据到缓冲区
RX3_End = 1;
AUXR &= ~(1<<4); //Timer2 停止运行
INT_CLKO |= (1 << 6); //允许INT4中断
}else{
Rx3_DAT >>= 1; //把接收的单b数据 暂存到 RxShiftReg(接收缓冲)
if(P_RX3) Rx3_DAT |= 0x80; //shift RX data to RX buffer
}
}
if(Tx3_Ting){ // 不发送, 退出
if(Tx3_BitCnt == 0){ //发送计数器为0 表明单字节发送还没开始
P_TX3 = 0; //发送开始位
Tx3_DAT = Tx3_BUF; //把缓冲的数据放到发送的buff
Tx3_BitCnt = 9; //发送数据位数 (8数据位+1停止位)
}else{ //发送计数器为非0 正在发送数据
if (--Tx3_BitCnt == 0){ //发送计数器减为0 表明单字节发送结束
P_TX3 = 1; //送停止位数据
Tx3_Ting = 0; //发送停止
}else{
Tx3_DAT >>= 1; //把最低位送到 CY(益处标志位)
P_TX3 = CY; //发送一个bit数据
}
}
}
}
/********************* INT4中断函数 *************************/
void Ext_INT4 (void) interrupt 16{
AUXR &= ~(1<<4); //Timer2 停止运行
T2H = (65536 - (UART3_BitTime / 2 + UART3_BitTime)) / 256; //起始位 + 半个数据位
T2L = (65536 - (UART3_BitTime / 2 + UART3_BitTime)) % 256; //起始位 + 半个数据位
AUXR |= (1<<4); //Timer2 开始运行
Rx3_Ring = 1; //标志已收到起始位
Rx3_BitCnt = 9; //初始化接收的数据位数(8个数据位+1个停止位)
INT_CLKO &= ~(1 << 6); //禁止INT4中断
T2H = (65536 - UART3_BitTime) / 256; //数据位
T2L = (65536 - UART3_BitTime) % 256; //数据位
}

链接
- 宏晶官网:http://www.stcmcu.com/
- STC15.PDF:https://gitee.com/openhwapi/IC/raw/master/STC15/DOC/STC15.pdf
- STC-TOOL.pdf:http://www.stcmcudata.com/STC-TOOL.pdf

@beautifulzzzz
智能硬件、物联网,热爱技术,关注产品
博客:http://blog.beautifulzzzz.com
园友交流群:414948975
[15单片机] STC15F104W开发入门及模拟串口程序的更多相关文章
- 【SpringBoot学习一】开发入门--快速创建springboot程序
前言 本片博客记录快速创建springboot工程的两种方式.一种是使用maven创建,一种是使用spring initializr创建.开发环境JDK1.8.IDEA.maven. SpringBo ...
- 微信小程序开发入门学习(2):小程序的布局
概述 小程序的布局采用了和Css3中相同的 flex(弹性布局)方式,使用方法也类似(只是属性名不同而已). 水平排列 默认是从左向右水平依次放置组件,从上到下依次放置组件. 任何可视组件都需要使用样 ...
- stc15f104w模拟串口使用
stc15f104w单片机体积小,全8个引脚完全够一般的控制使用,最小系统也就是个电路滤波----加上一个47uf电容和一个103电容即可,但因为其是一个5V单片机,供电需要使用5V左右电源. 该款单 ...
- Delphi 使用串口模拟工具进行串口程序开发调试
版权声明:本文为博主原创文章,如需转载请注明出处及作者. 本文由小李专栏原创,转载需注明出处:[http://blog.csdn.net/softwave/article/details/8907 ...
- Kinect for Windows SDK开发入门(15):进阶指引 下
Kinect for Windows SDK开发入门(十五):进阶指引 下 上一篇文章介绍了Kinect for Windows SDK进阶开发需要了解的一些内容,包括影像处理Coding4Fun K ...
- 51单片机GPIO口模拟串口通信
51单片机GPIO口模拟串口通信 标签: bytetimer终端存储 2011-08-03 11:06 6387人阅读 评论(2) 收藏 举报 本文章已收录于: 分类: 深入C语言(20) 作者同 ...
- Arduino可穿戴开发入门教程(大学霸内部资料)
Arduino可穿戴开发入门教程(大学霸内部资料) 试读下载地址:链接:http://pan.baidu.com/s/1mg9To28 密码:z5v8 介绍:Arduino可穿戴开发入门教程(大学霸内 ...
- 【CC2530入门教程-01】CC2530微控制器开发入门基础
[引言] 本系列教程就有关CC2530单片机应用入门基础的实训案例进行分析,主要包括以下6部分的内容:[1]CC2530微控制器开发入门基础.[2]通用I/O端口的输入和输出.[3]外部中断初步应用. ...
- AVR单片机教程——开发板介绍
本教程使用EasyElectronics开发板: EasyElectronics是一款基于AVR单片机的开发板.AVR单片机是基于改进的哈佛架构.8~32位的一系列RISC微控制器,最初由Atmel公 ...
随机推荐
- 芝麻HTTP:记scikit-learn贝叶斯文本分类的坑
基本步骤: 1.训练素材分类: 我是参考官方的目录结构: 每个目录中放对应的文本,一个txt文件一篇对应的文章:就像下面这样 需要注意的是所有素材比例请保持在相同的比例(根据训练结果酌情调整.不可比例 ...
- 三十天学不会TCP,UDP/IP网络编程 - 绅士的开始
经过了过年的忙碌和年初的懈怠一切的日子,我又开始重新更新了~这是最新的一篇~完整版可以去gitbook(https://www.gitbook.com/@rogerzhu/)看到. 如果对和程序员有关 ...
- Java反射机制应用实践
反射基础 在应用反射机制之前,首先我们先来看一下如何获取一个对象对应的反射类Class,在Java中我们有三种方法可以获取一个对象的反射类. 通过getClass方法 在Java中,每一个Object ...
- SpringBoot集成Shiro并用MongoDB做Session存储
之前项目鉴权一直使用的Shiro,那是在Spring MVC里面使用的比较多,而且都是用XML来配置,用Shiro来做权限控制相对比较简单而且成熟,而且我一直都把Shiro的session放在mong ...
- A Dream (PKUWC 2018)
A Dream (PKUWC 2018) 这是一个梦. 从没有几分节日气氛的圣诞,做到了大雪纷飞的数九寒天. 忘了罢! 不记得时间,不记得地点.随着记忆的褪去,一切也只会不复存在. Day-34? D ...
- [Luogu4074][WC2013]糖果公园
BZOJ权限题!提供洛谷链接 sol 树上带修改莫队 很显然吧.对吧. 所以说树上莫队要怎么写呢? 我们知道莫队=给区间排序+依次暴力处理,所以对于树上莫队而言也是一样的. 序列莫队基于序列分块(也就 ...
- LightOJ1245 Harmonic Number (II)
题意 \(求\Sigma \lfloor \frac{n}{i} \rfloor\) Input starts with an integer T (≤ 1000), denoting the num ...
- js实现简单的轮播效果
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- FTP环境搭建及客户代码调用公共方法封装
一.背景 大型系统架构往往被分解为多个独立可运行的组件, 以满足性能.可靠性.可扩展性的需求.多个组件间的数据交互往往采用两种方式:小量数据通过Sock函数.RMI.WebService等接口方式传递 ...
- 用python给html里的css及js文件链接自动添加版本号
传统的给文件链接添加版本号的方法是使用gulp-rev,这里提出的解决方案是使用python来替代gulp-rev. import os import re import uuid import sy ...