中微8S6990使用过程的一些记录--GPIO初始化、定时器、PWM、ADC、休眠等外设的配置和使用

news2024/9/23 11:21:50

前言

最近把一款产品的代码从新唐MS51移植到了中微8S6990平台上,记录下移植过程遇到的各种情况。

目录

  • 前言
    • 定时器初始化、中断服务函数
    • GPIO配置
    • ADC模数转换初始化
    • PWM初始化
    • Main函数
    • 休眠的一些注意事项
    • 最后

定时器初始化、中断服务函数

void TMR0_Config(void)
{
    /*
    (1)设置Timer的运行模式
    */
    TMR_ConfigRunMode(TMR0, TMR_MODE_TIMING,TMR_TIM_16BIT);	
    /*
    (2)设置Timer 运行时钟
    */
    TMR_ConfigTimerClk(TMR0, TMR_CLK_DIV_12);					/*Fsys = 24Mhz,Ftimer = 2Mhz,Ttmr=0.5us*/
    /*
    (3)设置Timer周期
    */	
    TMR_ConfigTimerPeriod(TMR0, (65535-2000)>>8, 65535-2000); 				// 2000*0.5us = 1000us,递增计数
        
    /*
    (4)开启中断
    */
    TMR_EnableOverflowInt(TMR0);

    /*
    (5)设置Timer中断优先级
    */	
    IRQ_SET_PRIORITY(IRQ_TMR0,IRQ_PRIORITY_LOW);
    

    /*
    (6)开启Timer
    */
    TMR_Start(TMR0);
}


void TMR1_Config(void)
{
    /*
    (1)设置Timer的运行模式
    */
    TMR_ConfigRunMode(TMR1, TMR_MODE_TIMING,TMR_TIM_16BIT);	
    /*
    (2)设置Timer 运行时钟
    */
    TMR_ConfigTimerClk(TMR1, TMR_CLK_DIV_12);						/*Fsys = 24Mhz,Ftimer = 2Mhz,Ttmr=0.5us*/
    /*
    (3)设置Timer周期
    */	
    TMR_ConfigTimerPeriod(TMR1, (65536-20000)>>8, 65536-20000); 				// 20000*0.5us = 10000us,递增计数
        
    /*
    (4)开启中断
    */
    TMR_EnableOverflowInt(TMR1);

    /*
    (5)设置Timer中断优先级
    */	
    IRQ_SET_PRIORITY(IRQ_TMR1,IRQ_PRIORITY_LOW);

    /*
    (6)开启Timer
    */
    TMR_Start(TMR1);
}

中断服务函数:

void Timer0_IRQHandler(void)  interrupt TMR0_VECTOR 
{	
	TH0 = (65535-2000)>>8;	//1ms
	TL0 = 65535-2000;
	
	TF0 = 0;			//可写可不写,进入中断硬件自动清零
	
}

void Timer1_IRQHandler(void)  interrupt TMR1_VECTOR 
{
	TH1 = (65536-20000)>>8;	//10ms
	TL1 = 65536-20000;
	
	TF1 = 0;
}

这两个是最基本的,没啥好说的,中断开起来之后就成功了一大半了。

GPIO配置

	/*三个按键*/
    GPIO_ENABLE_INPUT(P2TRIS,GPIO_PIN_4);		//设置输入/输出模式
    GPIO_ENABLE_INPUT(P2TRIS,GPIO_PIN_5);
    GPIO_ENABLE_INPUT(P2TRIS,GPIO_PIN_6);

    GPIO_ENABLE_UP(P2UP,GPIO_PIN_4);			//开上拉
    GPIO_ENABLE_UP(P2UP,GPIO_PIN_5);
    GPIO_ENABLE_UP(P2UP,GPIO_PIN_6);

    P24=1;P25=1;P26=1;

    /*ADC输入检测*/
    GPIO_ENABLE_INPUT(P3TRIS,GPIO_PIN_2);

    /*空闲IO 全部设置为输出高电平*/
    GPIO_ENABLE_OUTPUT(P3TRIS,GPIO_PIN_0);
    GPIO_ENABLE_OUTPUT(P3TRIS,GPIO_PIN_1);
    GPIO_ENABLE_OUTPUT(P3TRIS,GPIO_PIN_5);
    GPIO_ENABLE_OUTPUT(P3TRIS,GPIO_PIN_6);
    P30=1;P31=1;P35=1;P36=1;

    GPIO_ENABLE_OUTPUT(P0TRIS,GPIO_PIN_5);
    GPIO_ENABLE_OUTPUT(P0TRIS,GPIO_PIN_4);
    P04=1;P05=1;

    GPIO_ENABLE_OUTPUT(P2TRIS,GPIO_PIN_1);
    GPIO_ENABLE_OUTPUT(P2TRIS,GPIO_PIN_2);
    GPIO_ENABLE_OUTPUT(P2TRIS,GPIO_PIN_3);
    P21=1;P22=1;P23=1;

ADC模数转换初始化

/******************************************************************************
 ** \brief	 ADC_Config
 ** \param [in] 
 **            	
 ** \return  none
 ** \note  
 ******************************************************************************/
void ADC_Config(void)
{
	//设置ADC的运行模式
	ADC_ConfigRunMode(ADC_CLK_DIV_256, ADC_RESULT_LEFT);	//设置ADC时钟为系统时钟的256分频,ADC结果为左对齐,如有对ADC时钟有操作请参考"中微8051芯片ADC模块应用笔记"
	//设置ADC转换通道
	ADC_EnableChannel(ADC_CH_14);	
	GPIO_SET_MUX_MODE(P32CFG, GPIO_P32_MUX_AN14);			//设置端口复用功能 设置为复用为模拟输入通道14
	//设置ADC LDO	这个必须开启,相当于基准,6990是通过内部一个LDO来产生不同的基准的
	ADC_EnableLDO();
	ADC_ConfigADCVref(ADC_VREF_1P2V);						//ADC_VREF_1P2V, ADC_VREF_2V, ADC_VREF_2P4V, ADC_VREF_3V	
	
	//设置ADC中断
	ADC_DisableInt();

	//开启ADC
	ADC_Start();
}

PWM初始化

void PWM_Init(void)
{
    //设置EPWM运行模式 独立模式
    EPWM_ConfigRunMode(EPWM_OC_INDEPENDENT);

    //设置EPWM运行时钟	
    EPWM_ConfigChannelClk(EPWM0,EPWM_CLK_DIV_32);
    EPWM_ConfigChannelClk(EPWM1,EPWM_CLK_DIV_32);
    EPWM_ConfigChannelClk(EPWM2,EPWM_CLK_DIV_32);
    EPWM_ConfigChannelClk(EPWM3,EPWM_CLK_DIV_32);
    EPWM_ConfigChannelClk(EPWM4,EPWM_CLK_DIV_32);


    EPWM_ConfigChannelPeriod(EPWM0, 0x0190);        //总周期 400(十进制)
    EPWM_ConfigChannelPeriod(EPWM1, 0x0190);		
    EPWM_ConfigChannelPeriod(EPWM2, 0x0190);
    EPWM_ConfigChannelPeriod(EPWM3, 0x0190);
    EPWM_ConfigChannelPeriod(EPWM4, 0x0190);

    EPWM_ConfigChannelSymDuty(EPWM0, 0x0000);        
    EPWM_ConfigChannelSymDuty(EPWM1, 0x0000);
    EPWM_ConfigChannelSymDuty(EPWM2, 0x0000);
    EPWM_ConfigChannelSymDuty(EPWM3, 0x0000);
    EPWM_ConfigChannelSymDuty(EPWM4, 0x0000);

    //设置EPWM的加载方式为自动加载
    EPWM_EnableAutoLoadMode(EPWM_CH_0_MSK|EPWM_CH_1_MSK|EPWM_CH_2_MSK|EPWM_CH_3_MSK|EPWM_CH_4_MSK|EPWM_CH_5_MSK);
    //设置EPWM的输出极性
	EPWM_DisableReverseOutput(EPWM_CH_0_MSK|EPWM_CH_1_MSK|EPWM_CH_2_MSK|EPWM_CH_3_MSK|EPWM_CH_4_MSK); //关闭反向输出
    //设置EPWM输出
	EPWM_EnableOutput(EPWM_CH_0_MSK|EPWM_CH_1_MSK|EPWM_CH_2_MSK|EPWM_CH_3_MSK|EPWM_CH_4_MSK);		 //开启输出
    //设置EPWM死区 失能
	EPWM_DisableDeadZone(EPWM0);
    EPWM_DisableDeadZone(EPWM1);
	EPWM_DisableDeadZone(EPWM2);
    EPWM_DisableDeadZone(EPWM3);
	EPWM_DisableDeadZone(EPWM4);

    //设置EPWM输出IO复用
	GPIO_SET_MUX_MODE(P13CFG, GPIO_MUX_PG0);
	GPIO_SET_MUX_MODE(P14CFG, GPIO_MUX_PG1);
	GPIO_SET_MUX_MODE(P15CFG, GPIO_MUX_PG2);
	GPIO_SET_MUX_MODE(P16CFG, GPIO_MUX_PG3);
	GPIO_SET_MUX_MODE(P17CFG, GPIO_MUX_PG4);
	
	/*PWM 5个通道*/		
	//IO配置为输出一定要放在设置完PWM之后,不然上电配置好IO的初始状态时候,运行到PWM_init这个函数的时候所有IO状态会变得不确定
    GPIO_ENABLE_OUTPUT(P1TRIS,GPIO_PIN_3);
    GPIO_ENABLE_OUTPUT(P1TRIS,GPIO_PIN_4);
    GPIO_ENABLE_OUTPUT(P1TRIS,GPIO_PIN_5);
    GPIO_ENABLE_OUTPUT(P1TRIS,GPIO_PIN_6);
    GPIO_ENABLE_OUTPUT(P1TRIS,GPIO_PIN_7);
    P13=0;P14=0;P15=0;P16=0;P17=0;

    //开启EPWM
	EPWM_Start(EPWM_CH_0_MSK|EPWM_CH_1_MSK|EPWM_CH_2_MSK|EPWM_CH_3_MSK|EPWM_CH_4_MSK);
}

Main函数

int main(void)
{	
    SYS_DisableLVD();				//关闭LVD 功能  降低睡眠功耗
    WDT_DisableOverflowInt();		//关闭WDT中断

    GPIO_Init();
    GPIO_INT_Init();				//配置IO中断
    TMR0_Config();
    TMR1_Config();
    ADC_Config();
    PWM_Init();
    IRQ_ALL_ENABLE();				//开启总中断
    SYS_EnableWakeUp();             //使能STOP唤醒功能

    while(1)
    {
		while(ADC_IS_BUSY);								  //必须等ADC转换完才能关闭ADCEN
		 ADC_Stop();								      //关闭ADC
		 ADC_DisableLDO();								  //关闭ADC的LDO
		 SYS_EnterStop();                                 //休眠
    }
}

休眠的一些注意事项

首先,IO口肯定是要配置好进入睡眠前的状态。所有没用到的IO口,根据中微官方手册的建议是配置为输出模式,可以配置为输出高或低,不影响。

其次,ADC、ADC LDO、LSE、LVR还有PWM等外设模块,然后配置好IO中断(用于睡眠唤醒),调用库函数中的SYS_EnterStop(); 即可进入休眠模式。

进入休眠之后,唤醒MCU的时候有一个参数比较关键:
在这里插入图片描述
中微这个MCU比较有特色,唤醒之后还有一个稳定事件,过了稳定时间之后,才会把MCU唤醒并开始处理程序,这个时间在芯片设置里面调。
Keil里面打开魔术棒中的debug选项卡:
在这里插入图片描述
在右上角setting那里可以调整MCU的烧录配置:
在这里插入图片描述
下滑可以找到这个WAKEUP_WAITTIME,调整这个时间可以调整从睡眠状态唤醒之后开始执行语句的间隔时间,这个地方默认是1s,给人的感觉就是按了按键半天没反应,后来调整到50us之后,体感大大提升,基本上感觉不出来这个间隔时间。

最后

本项目移植过来就只需要用到上面这些模块,绝大多数代码都是参考中微官方提供的8S6990 Demo code来移植的,没什么技术含量,记录下来是为了方便日后使用,这篇博客就先分享到这。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/392540.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

keepalived+nginx 双机热备搭建

keepalivednginx 双机热备搭建一、准备工作1.1 准备两台centos7.91.2 nginx 与 keepalived软件 双机安装1.3 ip分配1.4 修改主机名1.5 关闭selinux(双机执行)1.6 修改hosts(双机执行)二、安装keepalived2.1 执行一下命令安装keepa…

MidiaPipe +stgcn(时空图卷积网络)实现人体姿态判断(单目标)

文章目录前言Midiapipe关键点检测stgcn 姿态评估效果前言 冒个泡,年少无知吹完的牛皮是要还的呀。 那么这里的话要做的一个东西就是一个人体的姿态判断,比如一个人是坐着还是站着还是摔倒了,如果摔倒了我们要做什么操作,之类的。…

【模型复现】-alexnet,nn.Sequential顺序结构构建网络

深度卷积神经网络(AlexNet) 在LeNet提出后的将近20年里,神经网络一度被其他机器学习方法超越,如支持向量机。虽然LeNet可以在早期的小数据集上取得好的成绩,但是在更大的真实数据集上的表现并不尽如人意。一方面&#…

第五章 事务管理

1.事务概念 *什么是事务:事务是数据库操作最基本单元,逻辑上是一组操作,要么都成功,要么都失败 *事务的特性(ACID):原子性、隔离性、一致性、持久性 2.搭建事务操作环境 *模拟场景&#xff…

uart串口接收模块

uart串口接收模块 1、UART(异步串行接口) 串行通信:指利用一条数据线将资料一位位的顺序传输。   异步通信:以一个字符为传输单位,通信中两个字符间的时间间隔是不固定的,然而在同一个字符的两个相邻位代…

【微信小程序】-- 页面事件 - 下拉刷新(二十五)

💌 所属专栏:【微信小程序开发教程】 😀 作  者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! &…

高盐废水除钙镁的技术解析

高盐废水指含有机物和至少总溶解固体(totaldissolvedsolids,tds)的质量分数大于3.5%的废水,具有水量大,无机盐离子k、na、ca2、mg2、cl-、so42-等含量高,水质水量变化大,成分复杂,难生化降解等特…

2023年中职网络安全竞赛——CMS网站渗透解析

需求环境可私信博主 解析如下: CMS网站渗透 任务环境说明: 服务器场景:Server2206(关闭链接) 服务器场景操作系统:未知 1.使用渗透机对服务器信息收集,并将服务器中网站服务端口号作为flag提交; Flag:8089

华为套件生态

华为套件生态前言蓝牙设备华为耳机华为鼠标智慧互联超级终端多屏协同远程访问文件共享华为电脑管家我的设备控制中心前言 华为的手机、平板、电脑、耳机、手环、手表等设备可以组成华为生态。以下分享一些生态体验。 蓝牙设备 华为耳机 快速连接 在手机/电脑附近打开华为耳…

里奇RIDGID管线定位仪/探测仪维修SR-20 SR-24 SR-60

美国里奇SeekTech SR-20管线定位仪对于初次使用定位仪的用户或经验丰富的用户,都同样可以轻易上手使用SR-20。SR-20提供许多设置和参数,使得大多数复杂的定位工作变得很容易。此外,当你在不复杂的环境下完成些基本的定位工作时,这…

软件测试7

一 CS和BS软件架构 CS:客户端-服务器端,BS:浏览器端-服务器端 区别总结: 1.效率:c/s效率高,某些内容已经安装在系统中了,b/s每次都要加载最新的数据 2.升级:b/s无缝升级&#xff0c…

【Maven】(五)Maven模块的继承与聚合 多模块项目组织构建

文章目录1.前言2.模块的继承2.1.可继承的标签2.2.超级POM2.3.手动引入自定义父POM3.模块的聚合3.1.聚合的注意事项3.2.反应堆(reactor)4.依赖管理及属性配置4.1.依赖管理4.2.属性配置5.总结1.前言 本系列文章记录了 Maven 从0开始到实战的过程,Maven 系列历史文章清…

三天吃透SpringMVC面试八股文

本文已经收录到Github仓库,该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点,欢迎star~ Github地址:https://github.com/…

【操作系统原理实验】命令解释器模拟实现

选择一种高级语言如C/C等,编写一类似于DOS、UNIX中的命令行解释程序。 1)设计系统命名行提示符; 2)自定义命令集(8-10个); 3)用户输入help命令以查找命令的帮助; 4)列出命令的功能,区分内部命令…

fuse文件系统调试环境

libfuse源码:GitHub - libfuse/libfuse: The reference implementation of the Linux FUSE (Filesystem in Userspace) interface 一、ubuntu20.04挂载fuse文件系统 1,安装编译工具 apt install ninja-build apt install meson apt install build-ess…

4. C#语法基础

一、cs文件结构 上面程序的各个部分说明如下: 程序的第一行using System; 其中【using】关键字用于在程序中包含 System 命名空间。一个程序一般有多个 using 语句。程序的第七行是 namespace 声明。一个 namespace 是一系列的类,MyFirstWinFormApp 命名…

SQL语句大全(MySQL入门到精通——基础篇)(基础篇——进阶篇——运维篇)

文章目录前言MySQL——基础篇一、SQL分类二、图形化界面工具三、DDL(Data Definition Language|数据定义语言)1.SQL-DDL-数据库操作2.SQL-DDL-表操作&查询3.SQL-DDL-数据类型3.SQL-DDL-表操作-修改&删除四、DML(Data Manipulation La…

经典模型LeNet跑Fashion-MNIST 代码解析

测试6.6. 卷积神经网络(LeNet) — 动手学深度学习 2.0.0 documentation import torch from torch import nn from d2l import torch as d2lnet nn.Sequential(#输入通道1表示黑白 输出通道6表示6组取不同特征的卷积核 因为卷积核是5*5,原始图片单通道黑…

面向对象设计模式:行为型模式之模板方法模式

一、模板方法引入:泡茶与冲咖啡 泡茶 烧水泡茶倒入杯子加入柠檬 冲咖啡 烧水冲咖啡倒入杯子加入牛奶和糖 二、模板方法,TemplateMethod 2.1 Intent 意图 Define the skeleton of an algorithm in an operation, deferring some steps to lets subclas…

【深度学习】BERT变体—BERT-wwm

1.BERT-wwm 1-1 Whole Word Masking Whole Word Masking (wwm)是谷歌在2019年5月31日发布的一项BERT的升级版本,主要更改了原预训练阶段的训练样本生成策略。 原有基于WordPiece的分词方式会把一个完整的词切分成若干个子词,在生成训练样本时&#xff…