高分跪求PIC 单片机I2C总线的例程

高分跪求PIC 单片机I2C总线的例程,第1张

这是pic16f873单片机的i2c总线的例子,先把数据写到at24c02上,然后再读回来,给数码管显示

#include<pic.h>

#define uchar unsigned char

#define uint unsigned int

#define add 0xaa

__CONFIG(0x3B31)

const uchar ee_data[]={1,2,3,4,5,6}

uchar read_data[6]

const uchar table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,

0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}

void delay(uint x)

void init()

void didi(uchar num)

void disp(uchar num1,uchar num2,uchar num3,uchar num4,uchar num5,uchar num6)

void write()

void read()

void main()

{

init()

write()

delay(100)

read()

while(1)

{

disp(read_data[0],read_data[1],read_data[2],read_data[3],read_data[4],read_data[5])

}

}

void delay(uint x)

{

uint a,b

for(a=xa>0a--)

for(b=110b>0b--)

}

void init()

{

TRISD=0

TRISA=0

TRISE0=0

// ADCON1=0x07

RE0=0

PORTD=0

PORTA=0

TRISC=0xff

SSPSTAT=0x80

SSPCON=0x38

SSPCON2=0

SSPADD=0x09

}

void write()

{

uchar i

SSPIF=0

SEN=1

while(!SSPIF)

SSPIF=0

SSPBUF=0xA0

while(!SSPIF)

SSPIF=0

SSPBUF=add

while(!SSPIF)

SSPIF=0

for(i=0i<6i++)

{

SSPBUF=ee_data[i]

while(!SSPIF)

SSPIF=0

}

PEN=1

while(!SSPIF)

SSPIF=0

}

void read()

{

uchar i

SSPIF=0

SEN=1

while(!SSPIF)

SSPIF=0

SSPBUF=0xA0

while(!SSPIF)

SSPIF=0

SSPBUF=add

while(!SSPIF)

SSPIF=0

SSPIF=0

RSEN=1

while(!SSPIF)

SSPIF=0

SSPBUF=0xA1

while(!SSPIF)

SSPIF=0

for(i=0i<6i++)

{

RCEN=1

while(!SSPIF)

read_data[i]=SSPBUF

while(!SSPIF)

SSPIF=0

if(i>=5)

{

ACKDT=1

}

else

{

ACKDT=0

}

ACKEN=1

while(!SSPIF)

SSPIF=0

}

PEN=1

while(!SSPIF)

SSPIF=0

}

void didi(uchar num)

{

uchar di_num

for(di_num=numdi_num>0di_num--)

{

RE0=1

delay(50)

RE0=0

delay(20)

}

}

void disp(uchar num1,uchar num2,uchar num3,uchar num4,uchar num5,uchar num6)

{

PORTD=table[num1]//显示第一个数码管

PORTA=0x20//0010 0000

delay(2)

PORTD=table[num2]//显示第二个数码管

PORTA=0x10//0001 0000

delay(2)

PORTD=table[num3]//显示第三个数码管

PORTA=0x08//0000 1000

delay(2)

PORTD=table[num4]//显示第四个数码管

PORTA=0x04//0000 0100

delay(2)

PORTD=table[num5]//显示第五个数码管

PORTA=0x02//0000 0010

delay(2)

PORTD=table[num6]//显示第六个数码管

PORTA=0x01//0000 0001

delay(2)

}

想知道哪种,给你粘贴,下面是一些计算子程序

******************************************************************

一、十六位二进制转换为BCD数子程序

******************************************************************

MOVLW 10H

MOVWF CNT

BCF STATUS,C

CLRF R2

CLRF R1

CLRF R0

LOOP RLF AL

RLF AH

RLF R0

RLF R1

RLF R2

DECFSZ CNT

GOTO ADJDEC

RETURN

ADJDEC MOVLW R0

MOVWF FSR

CALL ADJBCD

MOVLW R1

MOVWF FSR

CALL ADJBCD

MOVLW R2

MOVWF FSR

CALL ADJBCD

GOTO LOOP

ADJBCD MOVLW 3H

ADDWF INDF,W

MOVWF TMP

BTFSC TMP,3

MOVWF INDF

MOVLW 30H

ADDWF INDF,W

MOVWF TMP

BTFSC TMP,7

MOVWF INDF

RETURN

***************************************************************************

乘法宏

两个八位无符号数乘法,乘积为十六位。部分积右移相加算法:乘数带进位右移一位,

检查进位是否为一,若是一,部分积寄存器加被乘数,否则不加;然后部分积寄存器

带进位右移一位;重复上述过程直至循环次数为八结束。

***************************************************************************

宏的引用格式:MUL A,B

完成 *** 作: (A)*(B)---(A,B)

影响状态位:C、Z和DC

8*8位乘法宏MUL,结果的高字节部分存入(A),低字节存入(B)

***************************************************************************

MUL MACRO A,B

LOCAL MLOOP

****************************************************************************

如只用乘法子程序,就下段。

****************************************************************************

CLRF TMPA

CLRF TMPB

MOVLW 8

MOVWF CNT

MOVF A,W

BCF STATUS,C

MLOOP RRF B

BTFSC STATUS,C

ADDWF TMPA

RRF TMPA

RRF TMPB

DECFSZ CNT

GOTO MLOOP

MOVF TMPA,W

MOVWF A

MOVF TMPB,W

MOVWF B

*****************************************************************************

ENDM

*****************************************************************************

除法宏DIV

除法是乘法的逆运算。与十进制长除法类似,从被除数的最高有效位开始,把被除数左移

一位至余数上,如果余数不够减去除数,则商寄存器左移,移入位为零,反之移入位为一

余数减去被除数,把被除数的下一位移至除数上。重复上述过程直至处理完所有位。

******************************************************************************

宏的引用格式:DIV A,B

完成 *** 作: (A)为商部分,(B)为余数部分

影响状态位:C、Z和DC

8/8位除法宏DIV,结果(A)为商部分,(B)为余数部分

***************************************************************************

DIV MACRO A,B

LOCAL MLOOP

****************************************************************************

如只用除法子程序,就下段。

****************************************************************************

MOVF A,W

MOVWF TMPA

MOVF B,W

MOVWF TMPB

MOVLW 8

MVOWF CNT

CLRF A

CLRF B

DLOOP BCF STATUS,C

RLF TMPA

RLF B

MOVF TMPB,W

SUBWF B,W

BTFSC STATUS,C

MOVWF B

RLF A

DECFSZ CNT

GOTO DLOOP

****************************************************************************

ENDM

****************************************************************************

间接寻址

CLRF R0 清除R0寄存器里的内容

MOVLW R0

MOVWF FSR 将R0寄存器的地址送入间接寻址指针FSR

MOVF INDF,0

MOWF TEMP 将间接寻址指针FSR所指地址R0寄存器里的内容送入TEMP

MOVLW 88H

MOVWF INDF 将88H送入间接寻址指针FSR所指地址R0寄存器里

*******************************************************************************

将两位BCD数送入显示

显示十位BCD数

DISPLAY SWAPF TEMP,W 将TEMP寄存器里的内容的高低字节交换并送入W

ANDLW 0FH 将0FH与W寄存器里的内容相与并送入W

CALL CODE_TAB 查表取段码

MOVWF PORTD 送入PORTD端口

MOVLW 1H

MOVWF PORTC 选通PORTC,1

CALL DELAY 调用延时

显示个位BCD数

MOVF TEMP,W

ANDLW 0FH

CALL CODE_TAB

MOVWF PORTD

MOVLW 2H

MOVWF PORTC

CALL DELAY

*********************************************************************************************

16位二进制除以8位二进制

;*******************************************************************************************

DIV16

MOVF A,0

MOVWF DIV_H

MOVF BX,0

MOVWF DIV_L 被除数高低字节分别送进各寄存器

MOVLW 9H

MOVWF DIVB ;将除数送进寄存器

MOVLW 10H

MOVWF CNT ;按被除数位数设定移位次数

CLRF AL

CLRF AH

CLRF BX

DLOOP

BCF STATUS,C

RLF DIV_L

RLF DIV_H

RLF BX

MOVF DIVB,W

SUBWF BX,W

BTFSC STATUS,C

MOVWF BX

RLF AL

RLF AH

DECFSZ CNT

GOTO DLOOP

RETURN

****************************************************************************************************

8位乘以16位二进制乘法运算程序

****************************************************************************************************

MUL8

CLRF TMPA 清除积的高位寄存器

CLRF TMPB 清除积的中位寄存器

CLRF TMPC 清除积的低位寄存器

MOVLW 10H 因为8位二进制乘以16位二进制,乘数为16位,移位乘数,所以移位次数为16次

MOVWF CNT

MOVF BX,W 将8位被乘数送进W

BCF STATUS,C

MLOOP RRF TEMP_H

RRF TEMP_L 带C循环右移16位乘数

BTFSC STATUS,C

ADDWF TMPA

RRF TMPA

RRF TMPB

RRF TMPC

DECFSZ CNT

GOTO MLOOP

MOVF TMPA,W

MOVWF AA

MOVF TMPB,W

MOVWF A

MOVF TMPC,W 将乘积送进各寄存器。

MOVWF BX

RETURN

#ifndef __PWM__H__

#define __PWM__H__

void pwm_ccp1(unsigned char a,unsigned char b)

void pwm_ccp2(unsigned char a,unsigned char b)

#endif

void pwm_ccp1(unsigned char a,unsigned char b)//左边PWM

//CCP1 模块的 PWM 工作方式,周期为(b+1)*4*Tosc*(TMR2前分频值)=b+1 us //pwm高电平=a:CCP1CON(第四五位)Tosc*(TMR2前分频值)

//pwm高电平=a:CCP1CON(第四五位)Tosc*(TMR2前分频值)

{//a>b时有最高转速

CCPR1L=a //* 设置工作循环的高 8bit 为 a

CCP1CON=0X0C //0000 1100 设置 CCP1 为 PWM 工作方式,且工作循环的低 bit2 为 11*/

CCP1IE=0//* 禁止总中断和外围中断 */

PR2=b //* 设置 PWM 周期 */

TRISC2=0 //* 设置 RC2/CCP1 为输出 */

T2CON=0X04 //* 0000 1000前分频比为 1:1 ,后分频器1:2,打开 TMR2 ,同时输出 PWM 信号 */

}

void pwm_ccp2(unsigned char a,unsigned char b) //右边PWM

//CCP2 模块的 PWM 工作方式,周期为(b+1)*4*Tosc*(TMR2前分频值),

//pwm高电平=a:CCP2CON(第四五位)Tosc*(TMR2前分频值)

{

CCPR2L=a //* 设置工作循环的高 8bit 为 a

CCP2CON=0X0C //* 设置 CCP2 为 PWM 工作方式,且工作循环的低 bit2 为 11*/

CCP2IE=0 //* 中断屏蔽

PR2=b //* 设置 PWM 周期 */

TRISC1=0 //* 设置 RC1/CCP2 为输出 */

T2CON=0X04 //* 前分频比为 1 ,打开 TMR2 ,同时输出 PWM 信号 */

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11823706.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-19
下一篇 2023-05-19

发表评论

登录后才能评论

评论列表(0条)

保存