0元购怎么在网站做,小微企业管理软件,手游代理免费平台,网站建设验收确认书1. IIC
1.1 定义#xff08;同步串行半双工通信总线#xff09; IIC#xff08;Inter-Integrated Circuit#xff09;又称I2C#xff0c;是是IICBus简称#xff0c;所以中文应该叫集成电路总线。是飞利浦公司在1980年代为了让主板、嵌入式系统或手机用以连接低速周边设备…1. IIC
1.1 定义同步串行半双工通信总线 IICInter-Integrated Circuit又称I2C是是IICBus简称所以中文应该叫集成电路总线。是飞利浦公司在1980年代为了让主板、嵌入式系统或手机用以连接低速周边设备而发展而来的一种同步串行半双工通信总线方式。该总线允许同时连接多个设备(芯片)。每块芯片在总线上拥有特定的地址。自2006年10月1日起使用I²C协议已经不需要支付专利费但制造商仍然需要付费以获取IIC从属设备地址。
1.2 作用
设备间通信I²C用于微控制器和各种外围设备如传感器、EEPROM、ADC/DAC、LCD显示器等之间的数据传输。多主多从结构I²C支持多主多从架构允许多个主设备和多个从设备在同一总线上通信。地址分配每个从设备在总线上都有一个唯一的地址主设备通过该地址来选择并与特定从设备通信。时钟同步I²C使用单主时钟同步主设备生成时钟信号从设备响应时钟信号进行数据传输。双向数据传输I²C支持双向数据传输主设备可以向从设备发送数据也可以从从设备读取数据。
1.3 IIC的组网模式 上图所示是IIC的总线的使用场景所有挂载在IIC总线上的设备都有两根信号线一根是数据线SDA另一根是时钟线SCL。这两个信号线都是双向的。 作为一种通信方式IIC总线在某一时刻总线只允许有一个设备处于发送状态所发出的数据被总线上所有的设备所接收。IIC通信协议包含有设备地址只有发送方携带的地址与某个接收方的地址相同时接收方才真正执行相关的指令。 IIC总线规定设备在空闲时两根总线都处于高电平状态。为保证这种状态数据线SDA和时钟线SCL都要外接上拉电阻。上拉电阻的阻值一般位4.7~10K。。I2C 总线标准模式下速度可以达到 100Kb/S快速模式下可以达到 400Kb/S。I2C 总线工作是按照一定的协议来运行的接下来就看一下 I2C 协议。
1.4 IIC代码
#include s3c2440.h
#include string.h
#include stdio.h
#include led.h
#include key.h
#include interrupt.h
#include delay.h
#include pwm.h#define ADDRESS 0X08void init_wdt(void) //初始化看门狗禁止启动,关闭看门狗
{WTCON ~(1 0);
}void init_clk(void)
{unsigned int t MPLLCON; //将PCLK频率存入变量设置好再进行修改防止频率修改中途器件因为频率过高而短路t ~((0xff 12) | (0x3f 4) | (3 0)); //利用锁相环将12MHz倍频t | ((127 12) | (2 4) | (1 0)); //配置fclk频率大约为400MhzCLKDIVN | ((2 1) | (1 0));//分频配置HCLK为100MHzHCLK为50MHz MPLLCON t;//将所有频率配置好再进行设置防止器件被烧坏
}unsigned char buffer[128] {0};//存储pc给s3c2440发送s3c2440接收到的字符串
unsigned char tmpbuffer[128];
unsigned int pos;//已经收到字符的个数下一个要收到字符的位置void uart0_handler(void)
{if (SUBSRCPND (1 0))//如果UART0接收到了数据{buffer[pos] URXH0; }SUBSRCPND SUBSRCPND;
}void init_uart0(void)
{unsigned int t 0;GPHCON ~(0x0f 4);GPHCON | ((2 6) | (2 4));//设置中断模式串口电路引脚寄存器功能t ULCON0; //9600 n 8 1 波特率? 校验位? 数据位? 停止位t ~(1 6);//不使用红外模式t ~(7 3);//无奇偶校验t ~(1 2);//每帧 1 个停止位t | (3 0);//每帧用于发送或接收的数据位的个数8位ULCON0 t;t UCON0; //s3c2440给电脑发送数据用轮询 电脑给s3c2440发送数据s3c2440接收数据触发中断t ~(3 10);//选PCLK给 UART 波特率t ~(3 8);//发送接收方式改为脉冲方式t ~(0x0f 4);// 都设置为普通模式t ~(0x0f 0);t | (0x05 0);//设置UART模式发送轮询 接收模式为中断UCON0 t;INTSUBMSK ~(1 0);//uart子中断改为可服务状态enable_irq(IRQ_UART0);//配置中断为IRQ模式,让中断处于可服务模式 //配置接收的中断register_irq(IRQ_UART0 ,uart0_handler);UBRDIV0 325;//波特率分频寄存器 50000000/9600/16-1约等于325pos 0;
}void uart0_send_char(unsigned char ch)
{UTXH0 ch; // UART0 要发送的数据 UART 发送缓冲 寄存器while(0 (UTRSTAT0 (1 2)));//数据发完的标志 UART TX/RX 状态 寄存器
}void send_buffer(const char *p, unsigned int len)
{unsigned int i;for(i 0;i len;i){uart0_send_char(*p);}
}int parse(const char *p, unsigned int len)//分析上位机pc端发送的信息
{int i 0;int n 0;unsigned char tmpnum 0;if (p[0] ! 0xaa || p[len-1] ! 0x0D)//判断起始校验位{n 0;}if (p[1] ! ADDRESS) //判断是否为正确的下位机{n 0;}for (i 0; i 8; i){tmpnum p[i];}if (p[8] ! tmpnum) //判断校验位是否正确{n 0;}if (0x01 p[2])//调频{n 1;}else if (0x02 p[2]) //点灯{n 2;}return n;
}int i2c_finished 0; //中断触发条件void i2c_handler(void)//一条指令发送结束当ACK回复结束触发中断
{i2c_finished 1;
} void init_i2c(void)//初始化IIC
{GPECON ~((unsigned int)0x0f 28);GPECON | ((unsigned int)0x0a 28);//初始化24C02的I2CSDA、I2CSCLIICCON | (1 7);//允许IIC 总线应答使能位 回复ACKIICCON | (1 6);//50000000/512约等于96000 小于100k IIC 总线发送时钟预分频器的时钟源选择位IICCON | (1 5);//IIC 总线 Tx/Rx 中断使能/禁止位 允许enable_irq(IRQ_I2C);//使能中断register_irq(IRQ_I2C, i2c_handler);//注册中断// GPECON ~((unsigned int)0x0F 28);
// GPECON | ((unsigned int)2 30) | (2 28);
//
// IICCON | (1 7) | (1 6) | (1 5);
// IICCON ~(0x0F 0);
//
// enable_irq(IRQ_I2C);
// register_iqr(IRQ_I2C, i2c_handler);
}void do_and_wait_ack(void)
{i2c_finished 0;IICCON ~(1 4); //发送使能清除挂起位while (0 i2c_finished)//判断是否发送完成{udelay(100);//不能立马读取要等一下 }
}void at24c02_write(unsigned char device_address, unsigned char reg_address, const unsigned char *data, unsigned char n)//主机写——设备地址、寄存器地址、要写入数据的指针、数据字节数
{unsigned int i 0;IICDS device_address;//写设备地址IICSTAT 0xF0; //模式选择 主发送模式、产生起始信号、使能 Rx/Txdo_and_wait_ack();//使能数据发送并等待发送结束返回ack触发中断IICDS reg_address;//写设备中寄存器地址do_and_wait_ack();//使能数据发送并等待发送结束返回ack触发中断for (i 0; i n; i)//页写循环发送所有数据{IICDS *data;do_and_wait_ack(); }IICSTAT 0xD0;//模式选择 主发送信号、产生停止信号、使能 Rx/TxIICCON ~(1 4); //发送使能清除挂起位udelay(100);//
}void at24c02_read(unsigned char device_address, unsigned char reg_address, unsigned char *data, unsigned char n)//主机读从机发数据给主机——设备地址、寄存器地址、要读出数据的指针、数据字节数
{unsigned int i 0;IICDS device_address;//写设备地址IICSTAT 0xF0; //模式选择 主发送模式、产生起始信号、使能 Rx/Txdo_and_wait_ack();//使能数据发送并等待发送结束返回ack触发中断IICDS reg_address;//写设备中寄存器地址do_and_wait_ack();//使能数据发送并等待发送结束返回ack触发中断IICDS device_address;//写设备地址IICSTAT 0xB0; //模式选择 主接收模式、产生起始信号、使能 Rx/Txdo_and_wait_ack();//使能数据发送并等待发送结束返回ack触发中断*data IICDS; //第一次没用do_and_wait_ack(); for (i 0; i n; i){if ((n - 1) i){IICCON ~(1 7);//回复NACK }*data IICDS;do_and_wait_ack(); }IICSTAT 0x90;IICCON | (1 7);IICCON ~(1 4);udelay(100);
}int main(void)
{char s[100] {0};init_wdt();init_led();init_key();init_clk();init_delay();init_uart0();init_i2c();at24c02_write(0xA0, 0x00, ABCDEF, 6);at24c02_read(0xA0, 0x00, (unsigned char *)s, 6);while(1){if(pos ! 0){mdelay(100);at24c02_write(0xA0, 0x00, buffer, pos);at24c02_read(0xA0, 0x00, (unsigned char *)s, pos);send_buffer(s, pos);pos 0;} }}2. ADC滤波中值滤波、高斯滤波、高斯加权均值滤波、最小二乘法
#include s3c2440.h
#include string.h
#include stdio.h
#include led.h
#include key.h
#include interrupt.h
#include delay.h
#include pwm.h#define ADDRESS 0X08void init_wdt(void) //初始化看门狗禁止启动,关闭看门狗
{WTCON ~(1 0);
}void init_clk(void)
{unsigned int t MPLLCON; //将PCLK频率存入变量设置好再进行修改防止频率修改中途器件因为频率过高而短路t ~((0xff 12) | (0x3f 4) | (3 0)); //利用锁相环将12MHz倍频t | ((127 12) | (2 4) | (1 0)); //配置fclk频率大约为400MhzCLKDIVN | ((2 1) | (1 0));//分频配置HCLK为100MHzHCLK为50MHz MPLLCON t;//将所有频率配置好再进行设置防止器件被烧坏
}unsigned char buffer[128] {0};//存储pc给s3c2440发送s3c2440接收到的字符串
unsigned char tmpbuffer[128];
unsigned int pos;//已经收到字符的个数下一个要收到字符的位置void uart0_handler(void)
{if (SUBSRCPND (1 0))//如果UART0接收到了数据{buffer[pos] URXH0; }SUBSRCPND SUBSRCPND;
}void init_uart0(void)
{unsigned int t 0;GPHCON ~(0x0f 4);GPHCON | ((2 6) | (2 4));//设置中断模式串口电路引脚寄存器功能t ULCON0; //9600 n 8 1 波特率? 校验位? 数据位? 停止位t ~(1 6);//不使用红外模式t ~(7 3);//无奇偶校验t ~(1 2);//每帧 1 个停止位t | (3 0);//每帧用于发送或接收的数据位的个数8位ULCON0 t;t UCON0; //s3c2440给电脑发送数据用轮询 电脑给s3c2440发送数据s3c2440接收数据触发中断t ~(3 10);//选PCLK给 UART 波特率t ~(3 8);//发送接收方式改为脉冲方式t ~(0x0f 4);// 都设置为普通模式t ~(0x0f 0);t | (0x05 0);//设置UART模式发送轮询 接收模式为中断UCON0 t;INTSUBMSK ~(1 0);//uart子中断改为可服务状态enable_irq(IRQ_UART0);//配置中断为IRQ模式,让中断处于可服务模式 //配置接收的中断register_irq(IRQ_UART0 ,uart0_handler);UBRDIV0 325;//波特率分频寄存器 50000000/9600/16-1约等于325pos 0;
}void uart0_send_char(unsigned char ch)
{UTXH0 ch; // UART0 要发送的数据 UART 发送缓冲 寄存器while(0 (UTRSTAT0 (1 2)));//数据发完的标志 UART TX/RX 状态 寄存器
}void send_buffer(const char *p, unsigned int len)
{unsigned int i;for(i 0;i len;i){uart0_send_char(*p);}
}int parse(const char *p, unsigned int len)//分析上位机pc端发送的信息
{int i 0;int n 0;unsigned char tmpnum 0;if (p[0] ! 0xaa || p[len-1] ! 0x0D)//判断起始校验位{n 0;}if (p[1] ! ADDRESS) //判断是否为正确的下位机{n 0;}for (i 0; i 8; i){tmpnum p[i];}if (p[8] ! tmpnum) //判断校验位是否正确{n 0;}if (0x01 p[2])//调频{n 1;}else if (0x02 p[2]) //点灯{n 2;}return n;
}int i2c_finished 0; //中断触发条件void i2c_handler(void)//一条指令发送结束当ACK回复结束触发中断
{i2c_finished 1;
} void init_i2c(void)//初始化IIC
{GPECON ~((unsigned int)0x0f 28);GPECON | ((unsigned int)0x0a 28);//初始化24C02的I2CSDA、I2CSCLIICCON | (1 7);//允许IIC 总线应答使能位 回复ACKIICCON | (1 6);//50000000/512约等于96000 小于100k IIC 总线发送时钟预分频器的时钟源选择位IICCON | (1 5);//IIC 总线 Tx/Rx 中断使能/禁止位 允许enable_irq(IRQ_I2C);//使能中断register_irq(IRQ_I2C, i2c_handler);//注册中断// GPECON ~((unsigned int)0x0F 28);
// GPECON | ((unsigned int)2 30) | (2 28);
//
// IICCON | (1 7) | (1 6) | (1 5);
// IICCON ~(0x0F 0);
//
// enable_irq(IRQ_I2C);
// register_iqr(IRQ_I2C, i2c_handler);
}void do_and_wait_ack(void)
{i2c_finished 0;IICCON ~(1 4); //发送使能清除挂起位while (0 i2c_finished)//判断是否发送完成{udelay(100);//不能立马读取要等一下 }
}void at24c02_write(unsigned char device_address, unsigned char reg_address, const unsigned char *data, unsigned char n)//主机写——设备地址、寄存器地址、要写入数据的指针、数据字节数
{unsigned int i 0;IICDS device_address;//写设备地址IICSTAT 0xF0; //模式选择 主发送模式、产生起始信号、使能 Rx/Txdo_and_wait_ack();//使能数据发送并等待发送结束返回ack触发中断IICDS reg_address;//写设备中寄存器地址do_and_wait_ack();//使能数据发送并等待发送结束返回ack触发中断for (i 0; i n; i)//页写循环发送所有数据{IICDS *data;do_and_wait_ack(); }IICSTAT 0xD0;//模式选择 主发送信号、产生停止信号、使能 Rx/TxIICCON ~(1 4); //发送使能清除挂起位udelay(100);//
}void at24c02_read(unsigned char device_address, unsigned char reg_address, unsigned char *data, unsigned char n)//主机读从机发数据给主机——设备地址、寄存器地址、要读出数据的指针、数据字节数
{unsigned int i 0;IICDS device_address;//写设备地址IICSTAT 0xF0; //模式选择 主发送模式、产生起始信号、使能 Rx/Txdo_and_wait_ack();//使能数据发送并等待发送结束返回ack触发中断IICDS reg_address;//写设备中寄存器地址do_and_wait_ack();//使能数据发送并等待发送结束返回ack触发中断IICDS device_address;//写设备地址IICSTAT 0xB0; //模式选择 主接收模式、产生起始信号、使能 Rx/Txdo_and_wait_ack();//使能数据发送并等待发送结束返回ack触发中断*data IICDS; //第一次没用do_and_wait_ack(); for (i 0; i n; i){if ((n - 1) i){IICCON ~(1 7);//回复NACK }*data IICDS;do_and_wait_ack(); }IICSTAT 0x90;IICCON | (1 7);IICCON ~(1 4);udelay(100);
}void init_adc(void) //初始化ADC
{unsigned int t;t ADCCON;t | (1 14); //使能预分频t ~(0xff 6);t | (49 6);//给预分频值t ~(0x07 3);// 模拟输入通道选择AIN0引脚t ~(1 2);// 正常工作模式t | (1 1);//使能ADC转换ADCCON t;
}void do_adc(void)
{int i 0;unsigned int ret 0;//存每次转换好的ADC的值unsigned int adc_buffer[10];//存十次adc采样的值unsigned long long sum 0;//存十次采样的总和char s[10] {0};ret ADCDAT0;//取出转化的值for (i 0; i 10; i){while (0 (ADCCON (1 15)))//转换结束标志位、判断ADC是否处理结束ret ADCDAT0 0x3ff;//取出转化的值(只要低十位) adc_buffer[i] ret;}for (i 0; i 10; i){sum adc_buffer[i];}sprintf(s, %llu\n, sum / 10);//求平均值send_buffer((const char *)s, strlen(s));
}int main(void)
{
// char s[100] {0};init_wdt();init_led();init_key();init_clk();init_delay();init_uart0();init_i2c();init_adc();do_adc();
// at24c02_write(0xA0, 0x00, ABCDEF, 6);
// at24c02_read(0xA0, 0x00, (unsigned char *)s, 6);while(1){do_adc();
// if(pos ! 0)
// {
// mdelay(100);
// at24c02_write(0xA0, 0x00, buffer, pos);
// at24c02_read(0xA0, 0x00, (unsigned char *)s, pos);
// send_buffer(s, pos);
// pos 0;
// } }
}1. eeprom电容可擦除、可编程的rom
2. IIC总线上两根线都给高电平如何保证两根总线上为高电平给两根总线上都加上拉电阻
10k或4.7k 3.IIC数据高位先行
SCK时钟信号主机提供、数据信号SDA 主机在时钟高电平拉低数据线为起始主机在时钟高电平拉高终止
红主机、绿从机
主机写从机给主机应答ACK、
主机读主机给从机非应答NACK
时钟高电平数据要保持稳定
4. 面试问题
简述IIC时序
5.
末尾0往硬盘写数据1从硬盘读数据 6. 每完成一步 产生一次中断
7. 应答ack不应答nack 发ACK时刻产生中断 7. 第一次读取的数据是无效的 8. ADC只能转电压
八位0~255
十位0~1023
十二位0~4095
n位ADC为比较器的个数
ADC工作原理逐次逼近法类似于二分查找 ksps