手册参考E:\peixunQianrushi\jiekoubiancheng\ziliao\FS4412新版(学生资料)\原理图
由图可知,led2首先连接了一个三极管,然后连接到信号控制端口
所以我们首先要知道CHG_COK连接的cpu的哪个引脚
打开核心板手册
由上图可知我们的led2连接到GPX2_7
LED2 ---- 限流电阻 ---- 3级管 ----- CHG_COK ---- CPU --- XEINT23/KP_ROW7/ALV_DBG19/GPX2_7
LED2 ------ GPX2_7
LED3 ------ GPX1_0 //实验 点亮这个灯
LED4 ------ GPF3_4
LED5 ------ GPF3_5
有电路图可知 CPU --- GPX2_7 管脚 输出一个 高电平 对应 LED2 亮
NPN型三极管基极高电平导通,低电平截止
PNP 型三极管基极低电平导通,高电平截止
三极管的类型判断,先看箭头,因为三极管的电流是从P----->N的,由图可知三极管是NPN型,NPN三极管的基极接收一个高电平,三极管导通(接低电平三极管截止) 集电极和发射极产生电位差 led灯可以点亮
基本管脚功能 GPIO 通用输入输出功能
主要用于实现 管脚的输入(input) 输出(output)功能
4412芯片 GPIO管脚 有分组
GPX1_0: 表示该管脚 属于 GPX1 管脚组 _0 表示该管脚在组中的 0号位置
GPIO控制器 : 用于 控制管脚 输入或输出 功能的实现的 硬件结构
控制器: 芯片内部的硬件结构, 专门用于实现某种功能
gpio的 硬件结构:
输出: 即指 管脚 可以向外输出 信号 有电 1 没电 0
输入: 管脚 感受外部输入 信号 有电 1 没电 0
推挽输出: 数字信号1 输出到电平 数字信号0 输出低电平
开漏输出: 数字信号0 接到GND 输出低电平 数字信号1 断开连接 高阻态
程序中 具体使用什么输出方式 有 外部电路决定
LED3 ------ GPX1_0 //实验 点亮这个灯
芯片管脚控制 功能 查看芯片手册
参考E:\peixunQianrushi\jiekoubiancheng\ziliao\FS4412新版(学生资料)\芯片手册
看芯片手册 查 寄存器的 物理地址 然后访问操作
由芯片手册可得 113页
GPX1 控制器 有 4个寄存器
GPX1CON configuration register 配置寄存器
GPX1DAT data register 数据寄存器
GPX1PUD pull-up/ pull-down register 上下拉配置寄存器
GPX1DRV drive strength control register 驱动强度配置
GPX1CON : 355页
Address: 0x1100 0C20
配置 管脚 的 功能作用
GPX1CON [3:0] = 0x1 表示设置 GPX1_0为输出模式
翻译
当您配置端口作为输入端口时,相应的位是引脚状态。
当配置为输出端口时,引脚状态应与对应的位相同。
当端口配置为功能引脚时,将读取未定义的值
所以作为输出要点亮led 就输出高电平,及相应的位输出1
GPX1DAT: 0x1100_0C24
即配置 第[0]位 = 1 led 高电平亮
GPX1PUD: 0x1100 0C28
配置 第[1:0]位 = 0 //不使能上下拉
GPX1DRV: 对控制LED 驱动力 没有要求 不用配置
mb---main
volatile 防止编译器优化,修饰易变的量 主要用于修饰寄存器
//volatile 防止编译器优化,修饰易变的量
#define GPX1CON (*(volatile unsigned int*)0x11000c20)
#define GPX1DAT (*(volatile unsigned int*)0x11000c24)
#define GPX1PUD (*(volatile unsigned int*)0x11000c28)
int main()
{
//往内存地址 0x1100 0c20 的这几位[3:0]写入0x1 即[3:0]=0x1
// *((unsigned int*)0x11000c20) = (*((unsigned int*)0x11000c20) & ~(0xf<<0)) | (0x1 << 0);
GPX1CON = (GPX1CON & ~(0xf<<0)) | (0x1 << 0); //配置引脚模式 配置为输出模式
GPX1DAT |= 1;//配置数据寄存器,输出高电平
//GPX1PUD = GPX1PUD & ~(0x3<<0) | (0x00<<0);
//简化写法如下
GPX1PUD &= ~(0x3<<0);//配置上下拉配置寄存器,不使能上下拉
while(1);//阻塞程序
return 0;
}
FS4412 5.2 # loadb 0x40008000
## Ready for binary (kermit) download to 0x40008000 at 115200 bps...
## Total Size = 0x00000958 = 2392 Bytes
## Start Addr = 0x40008000
FS4412 5.2 # go 40008000
## Starting application at 0x40008000 ...
5) 观察程序运行现象
设置开发板环境变量 实现自动执行
set bootcmd loadb 0x40008000\;go 0x40008000
save
mb----main
// 点亮led4
#include "exynos_4412.h"
int main()
{
GPF3.CON = (GPF3.CON & ~(0xf << 16)) | (0x1 << 16); //配置引脚模式 配置为输出模式
GPF3.DAT |= 0x10;//配置数据寄存器,输出高电平 0001 0000
//简化写法如下
GPF3.PUD &= ~(0x3<<8);//配置上下拉配置寄存器,不使能上下拉
while(1);//阻塞程序
return 0;
}
mb---main
//灯闪烁
#include "exynos_4412.h"
void delay(int m){
int i;
while(m--){
for(i=0;i<10000;i++);
}
}
int main()
{
//往内存地址 0x1100 0c20 的这几位[3:0]写入0x1 即[3:0]=0x1
GPX1.CON = (GPX1.CON & ~(0xf<<0)) | (0x1 << 0); //配置引脚模式 配置为输出模式
//简化写法如下
GPX1.PUD &= ~(0x3<<0);//配置上下拉配置寄存器,不使能上下拉
while(1)
{
//亮 把0号bit设置为1
GPX1.DAT |= 1;//配置数据寄存器,输出高电平
//延时
delay(100);
//灭 把0号bit设置为0
GPX1.DAT &= ~1;
delay(100);
}
return 0;
}
water_led ----- main
#include "exynos_4412.h"
//流水灯
//延时
void delay(int m){
int i;
while(m--){
for(i=0;i<10000;i++);
}
}
void led2_init()
{
//配置引脚模式
GPX2.CON = (GPX2.CON & ~(0xf<<28)) | (0x1 << 28);
//配置数据寄存器
// GPX2.DAT |= 0x80; //1000 0000
GPX2.DAT &= ~(0x80);
//配置上下拉寄存器
GPX2.PUD &= ~(0x3<<14);
}
void led3_init()
{
//配置引脚模式
GPX1.CON = (GPX1.CON & ~(0xf<<0)) | (0x1 << 0);
//配置数据寄存器
// GPX1.DAT |= 1;
GPX1.DAT &= ~1;
//配置上下拉寄存器
GPX1.PUD &= ~(0x3<<0);
}
void led4_init()
{
GPF3.CON = (GPF3.CON & ~(0xf << 16)) | (0x1 << 16); //配置引脚模式 配置为输出模式
// GPF3.DAT |= 0x10;//配置数据寄存器,输出高电平 0001 0000
GPF3.DAT &= ~(0x10);
GPF3.PUD &= ~(0x3<<8);//配置上下拉配置寄存器,不使能上下拉
}
void led5_init()
{
GPF3.CON = (GPF3.CON & ~(0xf << 20)) | (0x1 << 20); //配置引脚模式 配置为输出模式
// GPF3.DAT |= 0x20;//配置数据寄存器,输出高电平 0010 0000
GPF3.DAT &= ~(0x20);
GPF3.PUD &= ~(0x3<<10);//配置上下拉配置寄存器,不使能上下拉
}
int main()
{
led2_init();
led3_init();
led4_init();
led5_init();
while(1){
//led2亮
GPX2.DAT |= 0x80;
delay(30);
GPX2.DAT &= ~(0x80);
delay(30);
//led3
GPX1.DAT |= 1;
delay(30);
GPX1.DAT &= ~1;
delay(30);
//led4
GPF3.DAT |= 0x10;
delay(30);
GPF3.DAT &= ~(0x10);
delay(30);
//led5
GPF3.DAT |= 0x20;
delay(30);
GPF3.DAT &= ~(0x20);
delay(30);
}
return 0;
}
key_test------led.h
#ifndef __LED_H
#define __LED_H
//初始化ADDR对应的gpio控制 对于bit管脚为 output 模式
void gpio_output(volatile void * addr, int bit);
//对 addr 的 bit 管脚 设置输出 out 状态
void gpio_set(volatile void * addr, int bit, int out);
void led_init();
#endif
key_test------led.c
#include "exynos_4412.h"
//初始化ADDR对应的gpio控制 对于bit管脚为 output 模式
void gpio_output(volatile void * addr, int bit)
{
//CON ADDR->CON [bit*4+3 : bit*4] = 0x1; //这里为什么是4 呢,因为手册里面每一个管脚都是4个bit
//((volatile gpx1 *)addr) 意思是将 传来的结构体实例地址 转换为结构体指针
((volatile gpx1 *)addr)->CON = (((volatile gpx1 *)addr)->CON & ~(0XF << (4 * bit )) | (0x1 << (4 * bit )));
//设置为不上下拉,不懂公式看手册
//PUD ADDR->PUD [2 *bit+1 : 2*bit] = 0x0
((volatile gpx1 *)addr)->PUD &= ~(0X3 << (2 * bit ));
}
//对 addr 的 bit 管脚 设置输出 out 状态
void gpio_set(volatile void * addr, int bit, int out)
{
if(out){ //输出高电平
((volatile gpx1 *)addr)->DAT |= 1<< bit;
}
else{ //输出低电平
((volatile gpx1 *)addr)->DAT &= ~(1 << bit);
}
}
//对所有灯初始化
void led_init()
{
gpio_output(&GPX1, 0); //gpx1_0
gpio_output(&GPX2, 7); //gpx2_7
gpio_output(&GPF3, 4);
gpio_output(&GPF3, 5);
}
key_test------main.c
#include "exynos_4412.h"
#include "led.h"
//流水灯升级版
//延时桉树
void delay(int m)
{
int i;
while(m--)
for(i=0; i < 10000 ; i++);
}
int main()
{
//初始化所有灯
led_init();
while(1)
{
gpio_set(&GPX2, 7, 1);
delay(100);
gpio_set(&GPX2, 7, 0);
gpio_set(&GPX1, 0, 1);
delay(100);
gpio_set(&GPX1, 0, 0);
gpio_set(&GPF3, 4, 1);
delay(100);
gpio_set(&GPF3, 4, 0);
gpio_set(&GPF3, 5, 1);
delay(100);
gpio_set(&GPF3, 5, 0);
}
return 0;
}