ARM第三天(LED下、蜂鸣器上)

GPC1CON寄存器 0xE020_0080
确定GPC1_3的管脚为输出
这里写图片描述

当GPC1_3的管脚的功能确定了输出功能后,具体如何输出高电平?
GPC1DAT寄存器 0xE020_0084

这里写图片描述
[4,0],五个管脚共用一个寄存器,一个寄存器占用一位

什么是上、下拉电阻?
CW210-Peripherial.pdf
这里写图片描述
上拉电阻:
如按键按下,则XEINT0管脚为低电平
如按键松开,则XEINT0管脚为高电平
如果没有外接3.3V电源和上拉电阻,当按键松开时XEINT0处于悬空,电平值不确定,可以为高电平,也可能为低电平。
因为如果不接上拉电阻,如果开关松开,XEINT0为低电平有两种情况:断开(悬空)、回路,这就失去了低电平的唯一性,所以要接一个上拉电阻来唯一确定管脚状态。
若外接3.3V电源和上拉电阻,保证了XEINT0在按键松开时,有确定的状态,为高电平;

下拉电阻:
这里写图片描述

如按键按下,则XEINT0管脚为高电平
如按键松开,则XEINT0管脚为低电平
如果没有外接GND和下拉电阻,当按键松开时XEINT0处于悬空,电平值不确定,可以为高电平,也可能为低电平。
若外接GND和上拉电阻,保证了XEINT0在按键松开时,有确定的状态,为低电平;

GPC1PUD 上下拉电阻寄存器 0xE0200088

这里写图片描述

我们这里将管脚的上下拉电阻禁用

Tarena:
1,将GPC1_3管脚设置为输出功能管脚
GPC1CON 0xE0200080
bit[15:12]为0001,表示输出功能
2,禁止GPC1_3管脚内部上下拉电阻
GPC1PUD 0xE0200088
bit[7:6]为00,表示禁止内部上拉、下拉
3,使GPC1_3管脚产生高低电平
GPC1DAT 0xE0200084
bit[3] =1 ,表示向三级管输出高电平,LED亮
bit[3] =0 ,表示向三级管输出低电平,LED灭

融慧广泽:
1,将GPC0_3管脚设置为输出功能管脚
GPC0CON 0xE0200060
bit[15:12]为0001,表示输出功能
2,禁止GPC0_3管脚内部上下拉电阻
GPC0PUD 0xE0200068
bit[7:6]为00,表示禁止内部上拉、下拉

3,使GPC0_3管脚产生高低电平
GPC0DAT 0xE0200064
bit[3] =1 ,表示向三级管输出高电平,LED亮
bit[3] =0 ,表示向三级管输出低电平,LED灭

led.h文件

#ifndef __LED_H__
#define __LED_H__H

#define GPC1CON (*((volatile unsigned int*)0xE0200080))
#define GPC1DAT (*((volatile unsigned int*)0xE0200084))
#define GPC1PUD (*((volatile unsigned int*)0xE0200088))

#endif

led.c文件

#include "led.h"
void led_main(void){
   //配置GPC1_3管脚为输出口,操作GPC1CON bit[15,12] 为 0001
   GPC1CON = (GPC1CON & 0xFFFF0FFF)|0x00001000;
   //2,禁止GPC1_3管脚内部上下拉电阻 操作GPC1PUD bit[7,6]为00
   GPC1PUD &=~0xC0 ;
   //3,使GPC1_3管脚输出高电平,GPC1DATA bit[3]为1
   GPC1DAT |=8 ;
}

编译与链接:

   #编译
   arm-linux-gcc -march=armv5te -nostdlib -c -o led.o led.c
   #链接
   arm-linux-ld -nostartfiles -nostadlib -Text=0x20008000 -e led_main -o led led.o

   #转换文件格式  把lef格式的文件转换成bind格式的文件
   arm-linux-objcopy -o binary led led.bin

如保让LED闪烁?

#include "led.h"

void delay(unsinged int n);

void led_main(void){
   //配置GPC1_3管脚为输出口,操作GPC1CON bit[15,12] 为 0001
   GPC1CON = (GPC1CON & 0xFFFF0FFF)|0x00001000;
   //2,禁止GPC1_3管脚内部上下拉电阻 操作GPC1PUD bit[7,6]为00
   GPC1PUD &=~0xC0 ;
   //3,使GPC1_3管脚输出高电平,GPC1DATA bit[3]为1
   //高电平和低电平
   //操作GPC1DAT bit[3]为1或0
   while(1){
      GPC1DAT |=8 ;
      delay(0x100000);
      GPC1DAT &= ~8; 
      delay(0x100000);
   }
}

void delay(unsinged int n){
   while(n){
      n--;
   }
}

arm-linux-gcc -march=armv5te -nostdlib -c -o led.o led.c
-march=armv5te:指定生成的指令架构的版本
-nostdlib:不使用标准库
arm-linux-ld -nostartfiles -nostadlib -Text=0x20008000 -e led_main -o led led.o
-nostartfiles:不使用启动文件
-nostadlib:不使用标准的库函数
-Text:指定代码段的起始地址
-e led_main:指定代码的起始位置,不起作用,只是为了消除警告

arm-linux-objcopy -O binary led led.bin

Makefile:

#elf格式的文件依赖于led.o
led:led.o 
        arm-linux-ld -nostartfiles -nostdlib -Ttext=0x20008000 -e led_main -o led led.o
        arm-linux-objcopy -o bin ary led led.bin

led.o:led.c
    arm-linux-gcc -march=armv5te -nostdlib -c -o led.o led.c
clean:
    rm -vf led.o led led.bin

以上makefile通用不强,因为写死了

PROG=led
BIN=$(PROG).bin
OBJS=led.o

LC=arm-linux-gcc
LD=arm-linux-ld
OBJCOPY=arm-linux-objcopy

LDFLAGS = nostartfiles -nostdlib
-Ttext 0x20008000 -e led_main
CFLAGS=-march=armv5te -nostblib

#编译规则
$(PROG):(OBJS)
        $(LD) $(LDFALGS) -o $(PROG) $(OBJS)
        $(OBJCOPY) -o binary $(PROG) $(BIN)
        cp $(BIN) /fttpboot 
led.o:led.c
    $(CC) $(CFLAGS) -c -o led.o led.c
clean:
        rm -vf $(OBJS) $(PROG) $(BIN)

通用版本:

PROG=led
BIN=$(PROG).bin
OBJS=led.o

LC=arm-linux-gcc
LD=arm-linux-ld
OBJCOPY=arm-linux-objcopy

LDFLAGS = nostartfiles -nostdlib
-Ttext 0x20008000 -e led_main
CFLAGS=-march=armv5te -nostblib

$(PROG):(OBJS)
        $(LD) $(LDFALGS) -o $(PROG) $(OBJS)
        $(OBJCOPY) -o binary $(PROG) $(BIN)
        cp $(BIN) /fttpboot 
%.o:%.c
    $(CC) $(CFLAGS) -c -o $@ $<
clean:
        rm -vf $(OBJS) $(PROG) $(BIN)

%.o:%.c , 这里的%其实表示*,代表所有

(CC) (CFLAGS) -c -o @ < ,其中
@.o < 表示 *.c
%、$ 是Makefile内部自定义好了的。

如何点蜂鸣器?
这里写图片描述
根据管脚核心板原理图中查找:
这里写图片描述
GPIO管脚的操作
GPD0_1:
GPD0组4个管脚
寄存器
GPD0CON bit[7,4]
GPD0PUD bit[3,2]
GPD0DAT bit[3,2]
然后查看数据手册

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是基于ARM Cortex-M系列微控制器的代码,使用Keil MDK-ARM软件进行编写和仿真: ```c #include "STM32F10x.h" // 引入STM32F10x系列的头文件 int main() { RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // 使能GPIOA时钟 RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // 使能TIM2时钟 GPIOA->CRL |= GPIO_CRL_MODE5; // 设置GPIOA.5为推挽输出模式 GPIOA->CRL &= ~GPIO_CRL_CNF5; // 设置GPIOA.5为通用推挽输出模式 TIM2->PSC = 7199; // 预分频器值,时钟频率为72MHz÷(7199+1)=10kHz TIM2->ARR = 999; // 自动重载值,计数器值为0-999,即1秒 TIM2->CR1 |= TIM_CR1_ARPE; // 自动重载使能 TIM2->DIER |= TIM_DIER_UIE; // 允许更新中断 NVIC_EnableIRQ(TIM2_IRQn); // 允许TIM2中断 TIM2->CR1 |= TIM_CR1_CEN; // 启动定时器2 RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; // 使能AFIO时钟 AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_JTAGDISABLE; // 禁用JTAG调试功能,以便使用PA15引脚作为通用IO口 RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // 使能GPIOA时钟 GPIOA->CRH |= GPIO_CRH_MODE15; // 设置GPIOA.15为推挽输出模式 GPIOA->CRH &= ~GPIO_CRH_CNF15; // 设置GPIOA.15为通用推挽输出模式 RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; // 使能TIM3时钟 TIM3->PSC = 7199; // 预分频器值,时钟频率为72MHz÷(7199+1)=10kHz TIM3->ARR = 4999; // 自动重载值,计数器值为0-4999,即0.5秒 TIM3->CR1 |= TIM_CR1_ARPE; // 自动重载使能 TIM3->CR1 |= TIM_CR1_CEN; // 启动定时器3 RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; // 使能ADC1时钟 ADC1->CR2 |= ADC_CR2_CAL; // 开始ADC1校准 while (!(ADC1->CR2 & ADC_CR2_CAL)); // 等待ADC1校准完成 ADC1->SQR3 |= ADC_SQR3_SQ1_1 | ADC_SQR3_SQ1_3; // 设置ADC1的第1个转换通道为PA3 ADC1->CR2 |= ADC_CR2_ADON; // 开启ADC1 uint16_t adc_value; while (1) { if (TIM3->SR & TIM_SR_UIF) { // TIM3溢出中断 TIM3->SR &= ~TIM_SR_UIF; // 清除中断标志 ADC1->CR2 |= ADC_CR2_SWSTART; // 开始ADC转换 while (!(ADC1->SR & ADC_SR_EOC)); // 等待转换完成 adc_value = ADC1->DR; // 读取ADC转换结果 if (adc_value > 500) { // 当温度超过25℃时 GPIOA->BSRR = GPIO_BSRR_BR15; // 熄灭LED灯 for (int i = 0; i < 100000; i++); // 延时 GPIOA->BSRR = GPIO_BSRR_BS15; // 点亮LED灯 for (int i = 0; i < 100000; i++); // 延时 } else { GPIOA->BSRR = GPIO_BSRR_BR15; // 熄灭LED灯 } } } } void TIM2_IRQHandler() { // 定时器2中断服务函数 if (TIM2->SR & TIM_SR_UIF) { // TIM2溢出中断 TIM2->SR &= ~TIM_SR_UIF; // 清除中断标志 GPIOA->BSRR = GPIO_BSRR_BS5; // 开启蜂鸣器 for (int i = 0; i < 100000; i++); // 延时 GPIOA->BSRR = GPIO_BSRR_BR5; // 关闭蜂鸣器 } } ``` 该代码使用了定时器2和定时器3来实现蜂鸣器LED灯的控制,ADC1用于读取温度传感器的模拟信号。定时器2的中断服务函数中,通过GPIOA.5控制蜂鸣器的开关;定时器3用于定时读取温度传感器的模拟信号,并且当温度超过25℃时,通过GPIOA.15控制LED灯流水闪烁。需要注意的是,该代码中禁用了JTAG调试功能,以便使用PA15引脚作为通用IO口。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值