STM8S系列程序示例
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM8S系列程序示例相关的知识,希望对你有一定的参考价值。
求STM8S系列程序示例(英语水平有限,所以程序中的解释要“中文解释”),最好是S105C4的!万分感谢!
参考技术A /********************************************** STM8S105* TIM2 TIM3输出PWM PD0 PD3 TIM3输出PWM,*********************************************/#include "STM8S105K.h"
#include "STM8S105_CLOCK.h"
typedef unsigned char u8;
typedef unsigned int u16;u16 value;
/*******************************************************************************
*** 函数名 : void SystemInit(void)
*** 功能描述: 系统初始化
*** 函数说明: 系统全局初始化
******************************************************************************/
void SystemInit(void)
SystemClock_Init();
CLK_PCKENR1 |= 0x60; //使能TIM2与TIM3与主频连接
PD_CR2 |= 0x80; //使能PD7口外部中断
/*******************************************************************************
*** 函数名 : void main(void)
*** 功能描述: 主函数
*** 函数说明:
******************************************************************************/
void GPIO_init(void)
PD_DDR = 0x1F; //配置PD端口的方向寄存器全输出
PD_CR1 = 0x1F; //设置PD为推挽输出
PB_DDR|= 0x04; //PB2输出
PB_CR1|= 0x04; //PB2推挽输出
PB_ODR|= 0x04; //开5V电源
void TIM2_init(void) //TIM2 CH1 工作于模式1
// TIM2_CCMR2= 0x60; // PWM 模式 1
TIM2_CCMR1= 0x60; // PWM 模式 1,TIM2 CH1
TIM2_CCER1= 0x03; // CC1配置为输出
//TIM2_CCER2= 0x03; // CC3使能
TIM2_ARRH = 0x03; // 配置PWM分辨率为10位,ARR=0x3FF
TIM2_ARRL = 0xFF; // PWM频率=8M/0x03FF=7820Hz
TIM2_CR1 |= 0x01; // 计数器使能,开始计数
void TIM3_init(void) //TIM3 CH1 ch2工作于模式2,1
TIM3_CCMR1= 0x70; //PWM模式2
TIM3_CCMR2= 0x60; // PWM 模式 1
TIM3_CCER1= 0x33; // CC1 CC2配置为输出,CH1 CH2
TIM3_ARRH = 0x03; // 配置PWM分辨率为10位,ARR=0x3FF
TIM3_ARRL = 0xFF; // PWM频率=8M/0x03FF=7820Hz
TIM3_CR1 = 0x01; // 计数器使能,开始计数
void Run(void)
//TIM2_CCR2H = (unsigned char)(value>>8); // 更新CC2比较寄存器
//TIM2_CCR2L = (unsigned char)(value);
TIM2_CCR1=value;
//TIM2_CCR3=value;
TIM3_CCR2=value;
TIM3_CCR1=value; //注意每个通道都要设CCR
void init_devices(void)
_asm("sim");
SystemInit();
GPIO_init();
TIM2_init();
TIM3_init();
_asm("rim");
void main( void )
init_devices();
while(1)
Run();
/****************************************************************************
*** 函数名 : @near @interrupt void TLI_IRQHandler (void)
*** 功能描述: 中断服务程序
*** 函数说明:
*****************************************************************************/
@near @interrupt void TLI_IRQHandler (void)
PD_CR2 &= 0x7F; //关PD7外部中断
value+=50;
while(value>1000)
value=0; PD_CR2 |= 0x80; //使能PD7口外部中断
return;
参考技术B STM8S主流系列
意法半导体的STM8S系列主流8位微控制器适于工业、消费类和计算机市场的多种应用,特别是要实现大批量的情况。基于STM8专有内核,STM8S系列采用ST的130纳米工艺技术和先进内核架构,主频达到24 MHz,处理能力高达20MIPS。嵌入式EEPROM、RC振荡器和全套标准外设为设计者提供了稳定且可靠的解决方案。
相关工具链,从经济型探索套件到更复杂的评估套件和第三方工具,为利用STM8S微控制器进行开发提供了极大方便。
STM8S系列包括四个产品线,具有不同特性,但是保持了全面兼容性和可升级性,从而减少了未来产品设计变更。
STM8S003/005/007超值型是入门级产品,具有基本功能。
STM8S103/105基本型提供了更多特性和封装选项。
STM8S20增强型配有全套外设,满足中、高端应用的性能要求。
STM8S专用型提供了更多模拟特性和专用固件解决方案。
STC15比较器做ADC程序示例
【STC15】比较器做ADC程序示例
- STC15系列单片机A/D转换的结构图
- SOP28引脚功能定义图
- 类似运放电路的
电压跟随器
。
主程序代码
- 这是一个官方给出的示例程序,可以在STC官网下载,STC15系列库函数与例程测试版。
/*---------------------------------------------------------------------*/
/* --- STC MCU International Limited ----------------------------------*/
/* --- STC 1T Series MCU Demo Programme -------------------------------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966 ------------------------*/
/* --- Web: www.GXWMCU.com --------------------------------------------*/
/* --- QQ: 800003751 -------------------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了宏晶科技的资料及程序 */
/*---------------------------------------------------------------------*/
/****************************
本示例在Keil开发环境下请选择Intel的8052芯片型号进行编译
本例程MCU的工作频率为22.1184MHz.
使用MCU自带的比较器进行ADC转换, 并通过串口输出结果. 用定时器0产生10us中断查询比较器的状态.
使用比较器做ADC, 原理图如下.
做ADC的原理是基于电荷平衡的计数式ADC.
电压从Vin输入, 通过100K+104滤波, 进入比较器的P5.5正输入端, 经过比较器的比较, 将结果输出到P1.5再通过100K+104滤波后送比较器P5.4负输入端,跟输入电压平衡.
设置两个变量: 计数周期(量程)adc_duty 和 比较结果高电平的计数值 adc, adc严格比例于输入电压.
ADC的基准就是P1.5的高电平. 如果高电平准确,比较器的放大倍数足够大,则ADC结果会很准确.
当比较结果为高电平,则P1.5输出1, 并且adc+1.
当比较结果为低电平,则P1.5输出0.
每一次比较都判断计数周期是否完成,完成则adc里的值就是ADC结果.
电荷平衡计数式ADC的性能类似数字万用表用的双积分ADC, 当计数周期为20ms的倍数时,具有很强的抗工频干扰能力,很好的线性和精度.
原理可以参考ADD3501(3 1/2位数字万用表)或ADD3701(3 3/4位数字万用表), 也可以参考AD7740 VFC电路.
例: 比较一次的时间间隔为10us, 量程为10000, 则做1次ADC的时间为100ms. 比较器的响应时间越短, 则完成ADC就越快.
由于要求每次比较时间间隔都要相等,所以用C编程最好在定时器中断里进行, 定时器设置为自动重装, 高优先级中断, 其它中断均低优先级.
用汇编的话, 保证比较输出电平处理的时间要相等.
100K
/| P5.5 ___
P1.2 /+|---------o-|___|- ------- Vin
.----< | P5.4 |
| \\-|---. |
| \\| | |
| | |
| ___ | |
'---|___|---o |
100K | |
--- ---
--- ---
104 | | 104
| |
=== ===
GND GND
******************************/
#define MAIN_Fosc 16000000L //定义主时钟(晶振频率)
#define BaudRate1 9600ul //定义波特率
#define ADC_SCALE 50000 //ADC满量程, 根据需要设置
#include "STC15Fxxxx.H"
/************* 本地常量声明 **************/
//CMPCR1
#define CMPEN 0x80 //1: 允许比较器, 0: 禁止,关闭比较器电源
#define CMPIF 0x40 //比较器中断标志, 包括上升沿或下降沿中断, 软件清0
#define PIE 0x20 //1: 比较结果由0变1, 产生上升沿中断
#define NIE 0x10 //1: 比较结果由1变0, 产生下降沿中断
#define PIS 0x08 //输入正极性选择, 0: 选择内部P5.5做正输入, 1: 由ADCIS[2:0]所选择的ADC输入端做正输入.
#define NIS 0x04 //输入负极性选择, 0: 选择内部BandGap电压BGv做负输入, 1: 选择外部P5.4做输入.
#define CMPOE 0x02 //1: 允许比较结果输出到P1.2, 0: 禁止.
#define CMPRES 0x01 //比较结果, 1: CMP+电平高于CMP-, 0: CMP+电平低于CMP-, 只读
//CMPCR2
#define INVCMPO 0x80 //1: 比较器输出取反, 0: 不取反
#define DISFLT 0x40 //1: 关闭0.1uF滤波, 0: 允许
#define LCDTY 0x00 //0~63, 比较结果变化延时周期数
#define TIM_16BitAutoReload 0
#define TIM_16Bit 1
#define TIM_8BitAutoReload 2
#define TIM_16BitAutoReloadNoMask 3
#define Pin0 0x01 //IO引脚 Px.0
#define Pin1 0x02 //IO引脚 Px.1
#define Pin2 0x04 //IO引脚 Px.2
#define Pin3 0x08 //IO引脚 Px.3
#define Pin4 0x10 //IO引脚 Px.4
#define Pin5 0x20 //IO引脚 Px.5
#define Pin6 0x40 //IO引脚 Px.6
#define Pin7 0x80 //IO引脚 Px.7
#define PinAll 0xFF //IO所有引脚
/************* 本地变量声明 **************/
//sbit P_ADC = P1^2; //P1.2 比较器转IO输出端
sbit P_ADC = P1^0; //P1.2 比较器转IO输出端
u16 adc; //ADC中间值, 用户层不可见
u16 adc_duty; //ADC计数周期, 用户层不可见
u16 adc_value; //ADC值, 用户层使用
bit adc_ok; //ADC结束标志, 为1则adc_value的值可用. 此标志给用户层查询,并且清0
/************* 本地函数声明 **************/
void TxString(u8 *puts);
void main(void)
u8 i;
u8 tmp[5];
//IO口初始化
// P1n_push_pull(Pin2); //P1.2设置为push-pull output
P1n_push_pull(Pin4); //P1.2设置为push-pull output
P5n_pure_input(Pin4+Pin5); //P5.4 P5.5设置为高阻输入
//比较器初始化
CMPCR1 = 0;//复位
CMPCR2 = 20; //比较结果变化延时周期数, 0~63
CMPCR1 |= CMPEN; //允许比较器 ENABLE,DISABLE
// CMPCR1 |= PIE; //允许上升沿中断 ENABLE,DISABLE
// CMPCR1 |= NIE; //允许下降沿中断 ENABLE,DISABLE
// CMPCR1 |= PIS; //输入正极性选择, 0: 选择内部P5.5做正输入, 1: 由ADCIS[2:0]所选择的ADC输入端做正输入.
CMPCR1 |= NIS; //输入负极性选择, 0: 选择内部BandGap电压BGv做负输入, 1: 选择外部P5.4做输入
// CMPCR1 |= CMPOE; //允许比较结果输出到P1.2, ENABLE,DISABLE
// CMPCR2 |= INVCMPO; //比较器输出取反, ENABLE,DISABLE
CMPCR2 |= DISFLT; //内部0.1uF滤波, ENABLE,DISABLE
//定时器0 初始化
TMOD &= ~0x0f;
Timer0_16bitAutoReload(); //设置为16位自动重装模式
Timer0_1T(); //设置为1T模式
ET0 = 1; //允许中断
PT0 = 1; //高优先级中断
TH0 = (u8)((65536 - MAIN_Fosc / 100000ul)>>8); //重装值 100KHZ, 10us, 65536 - (MAIN_Fosc)/100000
TL0 = (u8)( 65536 - MAIN_Fosc / 100000ul);
TR0 = 1; //开始运行
//串口1初始化
S1_USE_P30P31(); //UART1 使用P30 P31口 默认
// S1_USE_P36P37(); //UART1 使用P36 P37口
// S1_USE_P16P17(); //UART1 使用P16 P17口
S1_8bit(); //8位数据,波特率可变
S1_RX_Enable(); //允许接收
S1_TXD_RXD_OPEN(); //将TXD与RXD连接中继断开 默认
S1_BRT_UseTimer2(); //使用Timer2做波特率发生器
ES = 0; //禁止中断, 使用查询发送
Timer2_1T(); //Timer2 1T模式, 固定为16位自动重装
T2L = (65536 - (MAIN_Fosc/4/BaudRate1)); //设置波特率重装值
T2H = (65536 - (MAIN_Fosc/4/BaudRate1))>>8;
Timer2_Run(); //允许定时器2计数
EA = 1; //允许全局中断
TxString("\\r\\n使用比较器做ADC例子\\r\\n"); //SUART1发送一个字符串
while (1)
if(adc_ok) //等待ADC结束
adc_ok = 0; //清除ADC已结束标志
TxString("ADC = "); //转十进制
tmp[0] = adc_value / 10000 + '0';
tmp[1] = adc_value % 10000 / 1000 + '0';
tmp[2] = adc_value % 1000 / 100 + '0';
tmp[3] = adc_value % 100 / 10 + '0';
tmp[4] = adc_value % 10 + '0';
for(i=0; i<4; i++) //消无效0
if(tmp[i] != '0') break;
tmp[i] = ' ';
for(i=0; i<5; i++) //发串口
TI = 0;
SBUF = tmp[i];
while(!TI);
TI = 0;
TxString("\\r\\n");
TxString("\\r\\n使用比较器做ADC例子\\r\\n"); //SUART1发送一个字符串
void TxString(u8 *puts) //发送一个字符串
for (; *puts != 0; puts++) //遇到停止符0结束
TI = 0;
SBUF = *puts;
while(!TI);
TI = 0;
/********************* Timer0中断函数************************/
void timer0_int (void) interrupt TIMER0_VECTOR
if((CMPCR1 & CMPRES) == 0) P_ADC = 0; //比较器输出高电平
else //P_ADC输出低电平, 给负输入端做反馈.
P_ADC = 1; //P_ADC输出高电平, 给负输入端做反馈.
adc ++; //ADC计数+1
if(--adc_duty == 0) //ADC周期-1, 到0则ADC结束
adc_duty = ADC_SCALE; //周期计数赋初值
adc_value = adc; //保存ADC值
adc = 0; //清除ADC值
adc_ok = 1; //标志ADC已结束
以上是关于STM8S系列程序示例的主要内容,如果未能解决你的问题,请参考以下文章
STM8S系列基于IAR开发外部中断(EXTI)按键检测示例
STM8S系列基于IAR开发:蜂鸣器(BEEP)驱动功能模块示例