当前位置: 首页 > news >正文

ARM day7 day8 UART串口、PWM蜂鸣器、WDT看门狗、ADC数模转换

一、串口编程

    1.看原理图

        GPA1_0: RXD2
        GPA1_1: TXD2

    2.看芯片手册

        1)对外设置 (GPIO)
            GPA1CON: 0x11400020   3:0->0x2(RXD2)  7:4->0x2(TXD2)
        2)对内设置(uart)
            ULCON2: 0x13820000   0x3
            UCON2:  0x13820004   1:0->01(polling)  3:2->01(polling)
            UTRSTAT2: 0->1(ready read)  1->1(发送完成)
            UBRDIV2:0x13820028  53
            UFRACVAL2:0x1382002C 4
            
            UTXH2: 0x13820020   发送buffer
            URXH2: 0x13820024   接收buffer

    3.编程

        uart.c

    		#define GPA1CON (*((volatile unsigned int *)0x11400020))#define ULCON2 (*((volatile unsigned int *)0x13820000))#define UCON2 (*((volatile unsigned int *)0x13820004))#define UTRSTAT2 (*((volatile unsigned int *)0x13820010))#define UBRDIV2 (*((volatile unsigned int *)0x13820028))#define UFRACVAL2 (*((volatile unsigned int *)0x1382002C))#define UTXH2 (*((volatile unsigned int *)0x13820020))#define URXH2 (*((volatile unsigned int *)0x13820024))void uart_init(void) //初始化{//1.对外设置 (GPIO)GPA1CON &= ~0xff;  GPA1CON |= 0x22; //3:0->0x2(RXD2)  7:4->0x2(TXD2)	//2.对内设置(uart)ULCON2 =  0x3;//8 1 无UCON2 &= ~0xf; UCON2 |= 0x5; // 1:0->01(polling)  3:2->01(polling)UBRDIV2 = 53;UFRACVAL2 = 4;//波特率:115200}void putc(char ch){UTXH2 = ch;//发送数据while((UTRSTAT2 & 0x2) == 0);//等待发送完成}void puts(char *str)//一个一个发{while(*str){putc(*str);str++;}}char getc(void){char ch;while((UTRSTAT2 & 0x1) == 0);//等待接收缓冲区有数据ch = URXH2;//接收数据}void put_int(int num){char buf[100];int i = 0;if (0 == num)buf[i++] = '0';while (num) {buf[i] = num % 10 + '0';i++;num = num / 10;}int j, k;for (j=0,k=i-1; j < k; j++,k--) {char c = buf[j];buf[j] = buf[k];buf[k] = c;}buf[i] = '\r';buf[i+1] = '\n';buf[i+2] = '\0';puts(buf);}

        main.c

    			void mydelay(int x){int i = 0;while(x--)for(i=1000;i>0;i--);}int main(){uart_init(); //初始化while(1){puts("hello\r\n");mydelay(500);}return 0;}

练习:串口控制LED  输入0时灯亮 输入1时灯灭

二、PWM

    1.看原理图

    GPD0_0: XpwmTOUT0

    2.看芯片手册

    1)对外设置(GPIO)
        GPD0CON: 0x114000A0  3:0->0x2(TOUT0)
    2)对内设置
        TCFG0: 0x139D0000 7:0->255 (第一次分频)
        TCFG1: 0x139D0004 3:0 -> 0100(16分频)
        TCON:  0x139D0008 0->1/0(启动/关闭定时器) 1->1 1->0(manual off) 2->1(inveter on) 3->1(自动重装载)
        TCNTB0:  0x139D000C   300(周期值)
        TCMPB0: 0x139D0010   150(比较值)    

    3.编程

        pwm.c

#define GPD0CON (*(volatile unsigned int *)0x114000A0)
#define TCFG0 (*(volatile unsigned int *)0x139D0000)
#define TCFG1 (*(volatile unsigned int *)0x139D0004)
#define TCON (*(volatile unsigned int *)0x139D0008)
#define TCNTB0 (*(volatile unsigned int *)0x139D000C)
#define TCMPB0 (*(volatile unsigned int *)0x139D0010)void pwm_init()
{//1.对外设置(GPIO)GPD0CON &= ~0xf;GPD0CON |= 0x2;//3:0->0x2(TOUT0)//2.对内设置TCFG0 &= ~0xff;TCFG0 |= 255; //第一次分频TCFG1 &= ~0xf;TCFG1 |= 0x4;//第二次分频TCNTB0 = 300;//周期值TCMPB0 = 150;//比较值TCON &= ~0xf;TCON |= 0xe;TCON &= ~0x2; // 0->0(关闭定时器) 1->1 1->0(manual off) 2->1(inveter on) 3->1(自动重装载)
}void buzz_on()
{TCON |= 0x1; //0->1
}
void buzz_off()
{TCON &= ~0x1; // 0->0
}

三、看门狗定时器

    0.作用

        看门狗的作用就是防止程序发生死循环,或者说程序跑飞。

        在系统运行以后也就启动了看门狗的计数器,看门狗就开始自动计数,如果到了一定的时间还不去清看门狗,那么看门狗计数器就会溢出从而引起看门狗中断,造成系统复位。

    1.看原理图

   不需要

    2.看芯片手册

    WTCNT:0x10060008  3000 周期值
    WTCON: 0x10060000  0->1(reset enable) 4:3->11(128分频) 5->1(WDT enable) 15:8->255 (255分频)

    3.编程

        wdt.c

#define WTCNT (*((volatile unsigned int *)0x10060008))
#define WTCON (*((volatile unsigned int *)0x10060000))
void wdt_init()
{WTCNT = 3000;// 周期值 1s = 1/100MHZ/(255+1)/128 * 3000WTCON &= ~(0xff<<8);WTCON |= 255 << 8; //第一次分频 255分频WTCON |= 0x3 << 3;//第二次分频 128WTCON |= 0x1; //reset enableWTCON |= 0x1<<5; // WDT enable
}

四、ADC数模转换

    1.看原理图

XadcAIN3

    2.看芯片手册

    ADCCON: 0x126C0000  16->1(12bit的分辨率)  15(转换完成的标志位)  14->1(分频使能) 13:6->19(分频值: 132+1) 2->0(正常模式) 1->1() 0->1(ADC start)
    ADCDAT:0x126C000C   转换结果
    ADCMUX:0x126C001C 3:0->0x3

    3.编程

        adc.c

#define ADCCON (*((volatile unsigned int *)0x126C0000))
#define ADCDAT (*((volatile unsigned int *)0x126C000C))
#define ADCMUX (*((volatile unsigned int *)0x126C001C))
void adc_init(void)
{ADCCON |= 0x1 << 16;//12bit的分辨率  15(转换完成的标志位)  ADCCON |= 0x1 << 14; //分频使能ADCCON &= ~(0xff<<6);ADCCON |= 132 << 6;//分频值: 132+1ADCCON &= ~(0x1<<2); //正常模式ADCCON &= ~0x2; //转换完成再去读数据ADCMUX &= ~0x7;ADCMUX |= 0x3;//AIN3
}int readData(void)
{int data = 0;//保存转换之后的数字量int voltage = 0;//保存转换之后的电压ADCCON |= 0x1;//ADC使能while(ADCCON & (0x1<<15) == 0);//等待转换完成data = ADCDAT & 0xfff;//转换的数字量voltage = (1800 * (data+1)) / 4096;//电压值return voltage;}

Makefile

all:arm-none-linux-gnueabi-gcc -fno-builtin -nostdinc -c -o start.o start.sarm-none-linux-gnueabi-gcc -fno-builtin -nostdinc -c -o main.o main.carm-none-linux-gnueabi-gcc -fno-builtin -nostdinc -c -o uart.o uart.carm-none-linux-gnueabi-gcc -fno-builtin -nostdinc -c -o pwm.o pwm.carm-none-linux-gnueabi-gcc -fno-builtin -nostdinc -c -o wdt.o wdt.carm-none-linux-gnueabi-gcc -fno-builtin -nostdinc -c -o adc.o adc.carm-none-linux-gnueabi-ld start.o main.o uart.o pwm.o wdt.o adc.o -Tmap.lds -o pwm.elfarm-none-linux-gnueabi-objcopy -O binary pwm.elf pwm.binarm-none-linux-gnueabi-objdump -D pwm.elf > pwm.dis
clean:rm -rf *.bak *.o *.elf *.dis *.bin

五、中断编程

1.理解
    外部设备触发的一种异常;
2.好处
    能够让cpu及时响应外部设备的请求,即马上请求马上响应,提升的硬件的性能。
3.处理过程
    1)当多个中断同时发生时,CPU如何处理?
        优先级
    2)当cpu正在处理中断是,突然又来一个同级或低优先级的中断时,cpu如何处理?
        cpu一定先处理完当前的中断,再去处理新中断;
    3)中断标志位
        中断处理完之后一定要清除中断标志位。

六、按键中断编程(按一下K2 执行打印,需要用到串口)

    1.看原理图

    GPX1_1: EINT9 port:25  Id:57

    2.看芯片手册

    1)对外设置(GPIO)
        GPX1CON:      0x11000C20    7:4->0xF //EXT_INT41
        EXT_INT41CON: 0x11000E04   6:4->0x2 //下降沿触发
        EXT_INT41_MASK: 0x11000F04  1->0 //Enables Interrupt
        
        EXT_INT41_PEND: 0x11000F44 1->1 //清除GPIO中断标志位
    2)对内设置(INT)
        ICDISER_CPU: 0x10490104 25->1 //总使能 
        ICDIPTR14:0x10490838 0x01010101 //分发器
        ICDDCR: 0x10490000  0->1 //分发使能
        ICCICR_CPU0:0x10480000 0->1 //接口使能
        ICCPMR_CPU0:0x10480004 255 //优先级
        
        
        ICCEOIR_CPU0: 0x10480010 9:0->写中断ID //结束中断
        ICDICPR_CPU:  0x10490284 25->1  //清除GIC中断标志位
        ICCIAR_CPU0: 0x1048000C  9:0->ID //获取中断ID

    3.编程

irq.c

#include "uart.h"#define GPX1CON 		(*(volatile unsigned int *)0x11000C20)
#define EXT_INT41CON 	(*(volatile unsigned int *)0x11000E04)
#define EXT_INT41_MASK 	(*(volatile unsigned int *)0x11000F04)
#define EXT_INT41_PEND 	(*(volatile unsigned int *)0x11000F44)    
#define ICDISER_CPU 	(*(volatile unsigned int *)0x10490104)
#define ICDIPTR14 		(*(volatile unsigned int *)0x10490838)
#define ICDDCR 			(*(volatile unsigned int *)0x10490000)
#define ICCICR_CPU0 	(*(volatile unsigned int *)0x10480000) 
#define ICCPMR_CPU0 	(*(volatile unsigned int *)0x10480004)
#define ICCEOIR_CPU0 	(*(volatile unsigned int *)0x10480010)
#define ICDICPR_CPU 	(*(volatile unsigned int *)0x10490284)
#define ICCIAR_CPU0 	(*(volatile unsigned int *)0x1048000C)void irq_init(void)
{//1.对外设置(GPIO)GPX1CON |= 0xF << 4; //EXT_INT41EXT_INT41CON &= ~(0x7<<4);EXT_INT41CON |= 0x2<<4;//下降沿触发EXT_INT41_MASK &= ~(0x1<<1); //Enables Interrupt//2.对内设置(INT)ICDISER_CPU |= 0x1 << 25; //总使能 ICDIPTR14 = 0x01010101; //分发器ICDDCR |= 0x1; //分发使能ICCICR_CPU0 |= 0x1; //接口使能ICCPMR_CPU0 = 255; //优先级
}void do_irq(void)//自定义中断处理函数
{//1.判断是哪个irqint id = ICCIAR_CPU0 & 0x3ff; //获取中断IDswitch(id){case 57:putc('i');//处理中断EXT_INT41_PEND |= 0x1<<1; //清除GPIO中断标志位ICDICPR_CPU |= 0x1<<25;  //清除GIC中断标志位break;case 58:break;default:break;}ICCEOIR_CPU0 &= ~0x3ff; ICCEOIR_CPU0 |= id; //结束中断
}

start.s 

       .textb reset	@0x00 reset ldr pc,_undef_handler		@0x04 undefineldr pc, _swi_handler @0x08 swi  pc =* _swi_handleldr pc, _prefetch_abort_handler @0x0C prefetch abortldr pc, _data_abort_handler @0x10 data abortnop @保留ldr pc, _irq_handler @irq 0x18ldr pc, _fiq_handler @fiq 0x1c_swi_handler:.word swi_handler_irq_handler:.word irq_handler_fiq_handler:.word _fiq_handlerswi_handler:stmfd sp!,{r0-r12,lr}  @现场保护@处理ldmfd sp!,{r0-r12,pc}^ @cpsr=spsrirq_handler:stmfd sp!,{r0-r12,lr}  @现场保护@处理ldmfd sp!,{r0-r12,pc}^ @cpsr=spsr	reset: @reset异常的处理函数mov r0,#0x3mov r1,r0.end

main.c

void mydelay(int x)
{int i = 0;while(x--)for(i=1000;i>0;i--);
}int main()
{irq_init();//irq初始化uart_init(); //初始化while(1){putc('a');mydelay(500);}return 0;
}

相关文章:

  • 电脑加固态硬盘有什么好处
  • Google的guava缓存学习使用
  • vue创建组件和使用
  • 去除 inline-block 元素间间距的方法
  • c语言不定参数
  • html+css+javascript实现贪吃蛇游戏
  • C++高级编程——STL:list容器、set容器和map容器
  • Pytest基础
  • [pytorch入门] 6. 神经网络
  • 小程序样例3:根据日历创建待办事项
  • 数灵通丨可以实现抖音引流微信小程序了
  • 腾讯云短信开发
  • css中>>>、/deep/、::v-deep的作用和区别,element-ui自定义样式
  • Docker搭建私有仓库
  • java spring cloud 企业工程管理系统源码+二次开发+定制化服务
  • Cookie 在前端中的实践
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • Java 11 发布计划来了,已确定 3个 新特性!!
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • Linux编程学习笔记 | Linux多线程学习[2] - 线程的同步
  • MySQL Access denied for user 'root'@'localhost' 解决方法
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • React as a UI Runtime(五、列表)
  • SwizzleMethod 黑魔法
  • vue的全局变量和全局拦截请求器
  • 从 Android Sample ApiDemos 中学习 android.animation API 的用法
  • 从零开始的无人驾驶 1
  • 分布式熔断降级平台aegis
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 每天10道Java面试题,跟我走,offer有!
  • 前端 CSS : 5# 纯 CSS 实现24小时超市
  • 区块链将重新定义世界
  • 设计模式(12)迭代器模式(讲解+应用)
  • 时间复杂度与空间复杂度分析
  • 使用阿里云发布分布式网站,开发时候应该注意什么?
  • 国内开源镜像站点
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • #1015 : KMP算法
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (DFS + 剪枝)【洛谷P1731】 [NOI1999] 生日蛋糕
  • (备忘)Java Map 遍历
  • (南京观海微电子)——I3C协议介绍
  • (四) 虚拟摄像头vivi体验
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (转)LINQ之路
  • ****** 二 ******、软设笔记【数据结构】-KMP算法、树、二叉树
  • *Django中的Ajax 纯js的书写样式1
  • .net 8 发布了,试下微软最近强推的MAUI
  • .NET BackgroundWorker
  • .NET Core实战项目之CMS 第十二章 开发篇-Dapper封装CURD及仓储代码生成器实现
  • .NET delegate 委托 、 Event 事件,接口回调
  • .net 发送邮件
  • .NET 设计模式—简单工厂(Simple Factory Pattern)
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)
  • .NET/C# 编译期能确定的字符串会在字符串暂存池中不会被 GC 垃圾回收掉