目录
ADC使用
1.什么是ADC?
ADC(Analog-to-Digital Converter)即模拟数字转换器。
一、功能
ADC 的主要功能是将模拟信号转换为数字信号。在现实世界中,很多物理量如温度、压力、声音等都是以模拟信号的形式存在的。然而,数字系统(如计算机、微处理器等)只能处理数字信号。因此,需要 ADC 将模拟信号转换成数字信号,以便数字系统进行处理、存储和分析。
二、工作原理
ADC 通过对输入的模拟信号进行采样和量化来实现转换。采样是在一定的时间间隔内对模拟信号进行测量,得到一系列离散的样本值。量化则是将这些样本值转换为有限个数字值的过程。量化的精度取决于 ADC 的位数,位数越高,量化误差越小,转换的精度就越高。
三、参数指标
1. 分辨率:通常用位数来表示,如 8 位、12 位、16 位等。分辨率决定了 ADC 能够区分的最小模拟信号变化量。 2. 转换速率:指 ADC 每秒能够完成的转换次数。转换速率决定了 ADC 对快速变化的模拟信号的跟踪能力。 3. 精度:包括绝对精度和相对精度。绝对精度表示实际转换结果与理想转换结果之间的偏差;相对精度则是相对于满量程的偏差。 4. 输入范围:指 ADC 能够接受的模拟信号的幅度范围。
四、应用领域
1. 通信领域:在无线通信系统中,ADC 用于将接收到的模拟射频信号转换为数字信号进行处理。例如,手机中的基带芯片就包含了高性能的 ADC。 2. 仪器仪表:各种测量仪器如示波器、万用表等都需要 ADC 将模拟测量信号转换为数字信号进行显示和分析。 3. 工业控制:在工业自动化系统中,ADC 用于将传感器采集到的模拟信号转换为数字信号,以便控制器进行处理和控制。 4. 音频处理:在音频设备中,ADC 将模拟音频信号转换为数字信号进行存储、处理和播放。
2.如何配置s3c2440中的adc?
代码:
#include "adc.h"
void adc_init()
{
ADCCON = (1 << 14) | (19 << 6) | (1 << 1) ;
}
unsigned short adc_read(void)
{
unsigned short value = ADCDAT0 & 0x3ff;
while(!ADCCON & (1 << 15)) ;
value = ADCDAT0 & 0x3ff;
return value;
}
void set_channel(unsigned int num)
{
ADCCON &= ~(0x7 << 3);
ADCCON |= (num << 3);
}
中断
1.什么是中断?
在计算机系统中,中断是一种非常重要的机制。
一、定义
中断是指计算机在执行程序的过程中,由于出现了某些突发事件(如外部设备请求服务、定时器溢出等),暂停当前正在执行的程序,转而去执行相应的中断处理程序,处理完突发事件后再返回到被中断的程序继续执行。
二、中断的作用
1. 实现实时处理:当外部设备有数据需要处理时,可以通过中断请求让计算机立即响应,从而实现对外部事件的实时处理。 2. 提高系统效率:在没有中断的情况下,计算机需要不断地查询外部设备的状态,这种方式浪费了大量的 CPU 时间。而有了中断机制,CPU 可以在等待外部设备准备好数据的过程中执行其他任务,提高了系统的效率。 3. 实现多任务处理:中断可以让计算机在执行一个任务的同时,响应其他任务的请求,从而实现多任务处理。
三、中断的类型
1. 硬件中断:由外部设备(如键盘、鼠标、打印机等)产生的中断,通过硬件电路向 CPU 发送中断请求信号。 2. 软件中断:由程序中的特定指令(如 INT 指令)产生的中断,通常用于实现系统调用、异常处理等功能。
四、中断处理过程
1. 中断请求:当外部设备需要服务或发生突发事件时,向 CPU 发送中断请求信号。 2. 中断响应:CPU 在执行完当前指令后,检测到中断请求信号,如果允许中断,则暂停当前程序的执行,保存当前程序的状态(如程序计数器、寄存器等),然后转去执行相应的中断处理程序。 3. 中断处理:中断处理程序根据中断类型进行相应的处理,如读取外部设备的数据、处理异常情况等。 4. 中断返回:中断处理完成后,恢复被中断程序的状态,返回到被中断的程序继续执行。
2.如何配置中断?
代码:
#include <s3c2440.h>
#include "irq.h"
void eint8_init(void)
{
//配置GPG0引脚功能为EINT8
GPGCON &= ~(0x3 << 0);
GPGCON |= (0x2 << 0);
EXTINT1 &= ~(0x7 << 0);
EXTINT1 |= (0x2 << 0); // 下降沿触发
EINTMASK &= ~(1 << 8); // 使能eint8
INTMSK &= ~(1 << 5); // 使能eint8_23
}
static irq_handle_t irq_handle_vector[60];
void c_deal_irq(void)
{
unsigned int irq_num = INTOFFSET;
if(irq_num == 5)
{
irq_handle_vector[irq_num + 31]();
EINTPEND |= (1 << (irq_num + 3));
}
else
irq_handle_vector[irq_num]();
SRCPND |= (1 << irq_num);
INTPND = INTPND;
}
void register_irq_handle(unsigned int num, irq_handle_t handler)
{
irq_handle_vector[num] = handler;
}
preserve8 ;对齐规则
area reset, code, readonly ;设定属性
code32 ;使用32位位宽ARM
entry ;开始处
b start ;reset
nop ;undef
b deal_swi ;swi
nop ;prefetch abort
nop ;data abort
nop ;reserved
b deal_irq ;irq
nop ;fiq
deal_irq
sub lr, lr, #4 ;获得irq的值
stmfd sp!, {r4-r12, lr} ;保护现场
import c_deal_irq
bl c_deal_irq ;跳转对应的函数
ldmfd sp!, {r4-r12, pc}^ ;带模式切换的恢复现场
deal_swi
stmfd sp!, {r4-r12, lr} ;保护现场
sub r0, lr, #4 ;获得swi的值
ldr r1, [r0] ;取出swi的地址值
bic r0, r1, #(0xff << 24) ;取出swi的值
import c_deal_swi
bl c_deal_swi ;跳转执行swi的值对应的函数
ldmfd sp!, {r4-r12, pc}^ ;带模式切换的恢复现场
start
ldr sp, =0x40001000 ;初始化svc模式的栈
mrs r0, cpsr ;取出cpsr的值
bic r0, r0, #(1 << 7)
msr cpsr_c, r0
mrs r0, cpsr ;取出cpsr的值
bic r0, r0, #0x1f ;清零
orr r0, r0, #0x12 ;置一
msr cpsr_c, r0 ;切换工作模式到irq
ldr sp, =0x40000c00 ;初始化irq模式的栈
mrs r0, cpsr ;取出cpsr的值
bic r0, r0, #0x1f ;清零
orr r0, r0, #0x10 ;置一
msr cpsr_c, r0 ;切换工作模式到user
ldr sp, =0x40000800 ;初始化user模式的栈
import main
bl main
swi #7
end ;结束
UART
1.什么是UART?
在芯片和通信领域中,UART(Universal Asynchronous Receiver/Transmitter)即通用异步收发传输器。
一、功能
UART 主要用于在两个设备之间进行异步串行数据通信。它可以将并行数据转换为串行数据进行发送,同时也可以将接收到的串行数据转换为并行数据。
二、工作原理
1. 数据发送:发送方将并行数据加载到 UART 的发送数据寄存器中,UART 按照设定的波特率(数据传输速率)将数据逐位发送出去。每一位数据的发送时间由波特率决定。发送时通常会添加起始位、数据位、校验位和停止位等组成一帧数据。 2. 数据接收:接收方的 UART 持续监测输入线路上的信号。当检测到起始位时,开始接收数据位,并根据设定的波特率进行采样。接收完一帧数据后,进行校验(如果有校验位),然后将数据存储在接收数据寄存器中,供接收设备读取。
三、主要特点
1. 异步通信:发送和接收设备不需要同步时钟信号,而是通过起始位和停止位来实现数据的同步。这使得 UART 在不同时钟频率的设备之间进行通信时非常方便。 2. 简单易用:UART 的接口相对简单,只需要几根信号线(如发送线、接收线、地线等)就可以实现通信。 3. 广泛应用:UART 被广泛应用于各种电子设备中,如微控制器、计算机、传感器、通信模块等。它可以用于与其他设备进行数据交换、调试和监控等。
四、参数指标
1. 波特率:表示数据传输的速率,单位为比特每秒(bps)。常见的波特率有 9600、115200 等。 2. 数据位:表示每帧数据中的有效数据位数,常见的有 5 位、6 位、7 位、8 位等。 3. 校验位:用于检测数据传输过程中的错误,可以选择无校验、奇校验或偶校验。 4. 停止位:表示每帧数据结束的标志位,常见的有 1 位、1.5 位、2 位等。
2.UART的数据帧格式
- 数据帧格式:
- 起始位:当不传输数据时,UART 数据传输线通常保持高电压电平(逻辑 “1”)。要开始数据传输,发送方会将传输线从高电平拉到低电平,并保持 1 个时钟周期,这个低电平信号就是起始位,用于向接收方表示数据传输的开始。
- 数据位:紧接起始位之后的是数据位,数据位的个数可以根据具体需求进行设置,通常为 5 位到 8 位。如果使用奇偶校验位,数据帧长度一般是 5 位到 8 位;如果不使用奇偶校验位,数据帧长度可以是 9 位。数据位是要传输的实际信息,一般按照最低有效位优先(LSB First)的方式发送。
- 奇偶校验位(可选):奇偶校验位是在数据位之后的额外一位,用于检验数据传输过程中是否发生错误。奇偶校验分为奇校验和偶校验。如果是偶校验,数据帧中 “1” 的个数加上奇偶校验位后应为偶数;如果是奇校验,数据帧中 “1” 的个数加上奇偶校验位后应为奇数。接收方根据校验规则对接收到的数据进行校验,如果校验结果不匹配,则认为数据传输出现错误。
- 停止位:为了表示数据包结束,发送方将数据传输线从低电压驱动到高电压,并保持 1 到 2 位时间。停止位是数据帧的结束标志。
3.如何配置UART(s3c2440)
代码如下:
#include <s3c2440.h>
#include "uart.h"
void uart0_init(void)
{
//配置GPH2、3引脚功能为TXD、RXD
GPHCON &= ~(0xf << 4);
GPHCON |= (0xa << 4);
ULCON0 &= ~(1 << 6); //普通模式
ULCON0 &= ~(0x7 << 3); //无校验
ULCON0 &= ~(1 << 2); //1位停止位
ULCON0 |= (0x3 << 0); //8位数据位
UCON0 &= ~(0xf << 12);
UCON0 |= (4 << 12); // FCLK / 10
UCON2 |= (1 << 15); // 使能FCLK/n
UCON0 |= (0x3 << 10); //uart时钟选择为fclk/n
UCON0 &= ~(0xf << 0);
UCON0 |= (0x5 << 0); //中断或轮询模式
UBRDIV0 = 259; //波特率 9600
UFCON0 |= (1 << 0); //使能FIFO
UFCON0 |= (1 << 1); //复位RX FIFO
}
unsigned char uart_send(unsigned char * data, unsigned char len)
{
int i = 0;
for(i = 0; i < len; i++)
{
while(!(UTRSTAT0 & (1 << 2)));
UTXH0 = data[i];
}
return i;
}
unsigned char uart_recv(unsigned char * data, unsigned char len)
{
int i = 0;
unsigned char count = UFSTAT0 & 0x3f;
unsigned char num = (count < len) ? count : len;
for(i = 0; i < num; i++)
{
data[i] = URXH0;
}
return num;
}
void uart0_handler(void)
{
unsigned char count = UFSTAT0 & 0x3f;
unsigned char data[64] = {0};
int i = 0;
for(i = 0; i < count; i++)
{
data[i] = URXH0;
}
uart_send(data, i);
}
#include <s3c2440.h>
#include "irq.h"
void eint8_init(void)
{
//配置GPG0引脚功能为EINT8
GPGCON &= ~(0x3 << 0);
GPGCON |= (0x2 << 0);
EXTINT1 &= ~(0x7 << 0);
EXTINT1 |= (0x2 << 0); // 下降沿触发
EINTMASK &= ~(1 << 8); // 使能eint8
INTMSK &= ~(1 << 5); // 使能eint8_23
}
void uart0_irq_init(void)
{
//配置GPH2、3引脚功能为TXD、RXD
GPHCON &= ~(0xf << 4);
GPHCON |= (0xa << 4);
ULCON0 &= ~(1 << 6); //普通模式
ULCON0 &= ~(0x7 << 3); //无校验
ULCON0 &= ~(1 << 2); //1位停止位
ULCON0 |= (0x3 << 0); //8位数据位
UCON0 &= ~(0xf << 12);
UCON0 |= (4 << 12); // FCLK / 10
UCON2 |= (1 << 15); // 使能FCLK/n
UCON0 |= (0x3 << 10); //uart时钟选择为fclk/n
UCON0 &= ~(0xf << 0);
UCON0 |= (0x5 << 0); //中断或轮询模式
UBRDIV0 = 21; //波特率 9600
UFCON0 |= (1 << 0); //使能FIFO
UFCON0 |= (1 << 1); //复位RX FIFO
UFCON0 &= ~(0x3 << 4);
UFCON0 |= (0x1 << 4); //rxd触发深度8字节
UCON0 |= (1 << 7); //rx超时使能
INTMSK &= ~(1 << 28); //使能UART0中断
INTSUBMSK &= ~(1 << 0); //使能UART0_RXD中断
}
static irq_handle_t irq_handle_vector[60];
void c_deal_irq(void)
{
unsigned int irq_num = INTOFFSET;
if(irq_num == 5)
{
irq_handle_vector[irq_num + 31]();
EINTPEND |= (1 << (irq_num + 3));
}
else if(irq_num == 28)
{
if(SUBSRCPND & 0x1)
{
irq_handle_vector[39]();
SUBSRCPND |= 0x1;
}
}
else
irq_handle_vector[irq_num]();
SRCPND |= (1 << irq_num);
INTPND = INTPND;
}
void register_irq_handle(unsigned int num, irq_handle_t handler)
{
irq_handle_vector[num] = handler;
}
注意代码不全仅供参考