xuyuntangs

文章数:240 被阅读:410258

账号入驻

PIC简单例程

最新更新时间:2022-07-04
    阅读数:

----IIC 模拟- ---

#include "i2c.h"


/*******************************************************************************

* 函 数 名         : Delay1us()

* 函数功能           : 延时

* 输    入         : 无

* 输    出         : 无

*******************************************************************************/


void I2C_Delay10us ()

{

uchar a, b;

for (b= 10 ; b> 0 ; b--)

{

for (a= 5 ; a> 0 ; a--);

}

}

/*******************************************************************************

* 函 数 名         : I2C_Start()

* 函数功能           : 起始信号:在I2C_SCL时钟信号在高电平期间I2C_SDA信号产生一个下降沿

* 输    入         : 无

* 输    出         : 无

* 备    注         : 起始之后I2C_SDA和I2C_SCL都为0

*******************************************************************************/


void I2C_Start ()

{

TRISB0= 0 ;

TRISB1= 0 ;

I2C_SCL= 1 ;

I2C_SDA = 0 ;

I2C_Delay10us ();

I2C_SDA = 1 ;

I2C_Delay10us ();

I2C_SDA = 0 ;

I2C_SCL= 0 ;

}

/*******************************************************************************

* 函 数 名           : I2C_Stop()

* 函数功能             : 终止信号:在I2C_SCL时钟信号高电平期间I2C_SDA信号产生一个上升沿

* 输    入           : 无

* 输    出              : 无

* 备    注           : 结束之后保持I2C_SDA和I2C_SCL都为1;表示总线空闲

*******************************************************************************/


void I2C_Stop ()

{

TRISB0= 0 ;

TRISB1= 0 ;

I2C_SCL = 0 ;

I2C_SDA = 0 ;

I2C_Delay10us ();

I2C_SCL = 1 ;

I2C_Delay10us ();

I2C_SDA = 1 ;

I2C_Delay10us ();

I2C_SDA = 0 ;

}

/*******************************************************************************

* 函 数 名           : I2cSendByte(uchar num)

* 函数功能              : 通过I2C发送一个字节。在I2C_SCL时钟信号高电平期间,

*                    * 保持发送信号I2C_SDA保持稳定

* 输    入           : num ,ack

* 输    出              : 0或1。发送成功返回1,发送失败返回0

* 备    注           : 发送完一个字节I2C_SCL=0, 需要应答则应答设置为1,否则为0

*******************************************************************************/

uchar I2C_SendByte (uchar dat , uchar ack )

{

TRISB0= 0 ;

TRISB1= 0 ;

uchar i,b;

for (i= 0 ;i< 8 ;i++)

{

I2C_SDA= dat >> 7 ; //因为从最高位开始

dat = dat << 1 ; //把最高位变成次高位

I2C_SCL= 0 ;

I2C_Delay10us ();

I2C_SCL= 1 ;

I2C_Delay10us ();

I2C_SCL= 0 ;

}


I2C_SDA = 1 ;

I2C_Delay10us ();

TRISB1= 1 ;

I2C_SCL = 1 ;

while (I2C_SDA && ( ack == 1 )) //等待应答,也就是等待从设备把I2C_SDA拉低

{

b++;

if (b > 200 ) //如果超过200us没有应答发送失败,或者为非应答,表示接收结束

{

I2C_SCL = 0 ;

I2C_Delay10us ();

return 0 ;

}

}

I2C_SCL= 0 ;

I2C_Delay10us ();

TRISB0= 0 ;

TRISB1= 0 ;

return 1 ; //初始化成功返还1


}

/*******************************************************************************

* 函 数 名           : I2cReadByte()

* 函数功能             : 使用I2c读取一个字节

* 输    入           : 无

* 输    出              : dat

* 备    注           : 接收完一个字节I2C_SCL=0

*******************************************************************************/

uchar I2C_ReadByte ()

{

TRISB0= 0 ;

TRISB1= 0 ;

uchar a,dat= 0 ; //a来执行循环 dat用来接收数据

I2C_SDA= 1 ; //接收数据 因为数据是拉低的 要是置0的话 那就没办法接受1

I2C_Delay10us (); //让数据稳定的

for (a= 0 ;a< 8 ;a++)

{

TRISB1= 1 ;

I2C_SCL = 0 ;

I2C_Delay10us ();

dat=dat<< 1 ; //方便下次接收

dat|=I2C_SDA;

I2C_Delay10us ();

I2C_SCL = 1 ;

I2C_Delay10us ();

}

TRISB1= 0 ;

TRISB0= 0 ;

return dat;

}











#ifndef __I2C_H_

#define __I2C_H_


#include


//---重定义关键词---//

#ifndef uchar

#define uchar unsigned char

#endif


#ifndef uint

#define uint unsigned int

#endif


//--定义使用的IO口--//

#define I2C_SCL RB0

#define I2C_SDA RB1


//--声明全局变量--//

void I2C_Delay10us ();

void I2C_Start ();

void I2C_Stop ();

uchar I2C_SendByte ( uchar dat , uchar ack );

uchar I2C_ReadByte ();


#endif



- --- 24X xx使用 ---

void At24c02Write (uchar addr ,uchar dat )

{

I2C_Start ();

I2C_SendByte ( 0xa0 , 1 ); //发送写器件地址

I2C_SendByte ( addr , 1 ); //发送要写入内存地址

I2C_SendByte ( dat , 0 ); //发送数据

I2C_Stop ();

}

/*******************************************************************************

* 函 数 名         : unsigned char At24c02Read(unsigned char addr)

* 函数功能           : 读取24c02的一个地址的一个数据

* 输    入         : 无

* 输    出         : 无

*******************************************************************************/


uchar At24c02Read (uchar addr )

{

uchar num ;

I2C_Start ();

I2C_SendByte ( 0xa0 , 1 ); //发送写器件地址

I2C_SendByte ( addr , 1 ); //发送要写入内存地址

I2C_Start ();

I2C_SendByte ( 0xa1 , 0 ); //发送写器件地址

num = I2C_ReadByte (); //读取数据

I2C_Stop (); //读取完毕

return num ; //返还num

}


- ---TLC2543 驱动 ----

#include

//#include"lcd.h"

#include "stdio.h"

#include "HELLOPIC.h"

#define CS RB2

#define CLK RB3

#define SDI RB1

#define SDO RB0

int Read_TLC2543 (uchar chnal );

void main ()

{

int h ;

TRISB0= 1 ; //设置RB0为输入端口

TRISB1= 0 ; //设置RB为输出端口

TRISB2= 0 ; //设置RB为输出端口

TRISB3= 0 ; //设置RB为输出端口

TRISC= 0X00 ;

while ( 1 )

{

h = Read_TLC2543 ( 0x0a ); //选择通道还有一定的问题

h = h >> 4 ;

PORTC= h ;

delayms ( 10 );

}

}

int Read_TLC2543 (uchar chnal ) //设置通道

{

int ADC_Value ;

uchar i ;

CLK = 0 ; //时钟位置0

CS = 1 ; // 片选置0 开始转换

NOP (); NOP (); NOP (); //延时几个us让数据稳定下来

CS = 0 ; //开始转换

for ( i = 0 ; i < 8 ; i ++)

{

CLK = 1 ;

if (( chnal & 0x80 )!= 0 )

{

SDI = 1 ; //将数据写入芯片

chnal = chnal <<= 1 ; //将最低位晚上左移一位

}

else

{

SDI = 0 ;

chnal = chnal <<= 1 ; //将最低位晚上左移一位

}

CLK = 0 ;

if ( SDO ) //当输出高电平信号时

{

ADC_Value = ADC_Value | 0x0001 ; //接收到高电平最后一位+1

}

ADC_Value = ADC_Value <<= 1 ; //时钟来一次数据更新一次

}

SDI = 0 ;

for ( i = 0 ; i < 4 ; i ++)

{

if ( SDO ) //当输出高电平信号时

{

ADC_Value = ADC_Value | 0x0001 ; //接收到高电平最后一位+1

}

ADC_Value = ADC_Value <<= 1 ; //时钟来一次数据更新一次

CLK = 1 ;

CLK = 0 ;

}

CS = 1 ; //关闭片选

return ADC_Value ;

}


- --- 数字电压表 ----

#include

#include "stdio.h"

#include "lcd.h"

#include "HELLOPIC.h"

uchar tab [ 30 ];

void displaywc ();

void adc_show ();

void main ()

{

TRISC= 0x00 ; //设置pwm脚为输出模式

init ();

lcd_init ();

ADC_Config ();

while ( 1 )

{

adc_show ();

displaywc ();

}

}

void adc_show ()

{

int i , J ;

J = getadc ();

J =( J / 5.1 );

sprintf ( tab , "voltageprice: %02d" , J );

PORTB = 0X80 ; //从第一行第一个开始

lcd_enable ();

for ( i = 0 ; i < 16 ; i ++)

{

write ( tab [ i ]);

}

}

void displaywc ()

{

uchar i ;

const uchar welcome [] ={ "  digital volta  " };

PORTB = 0X80 + 0X40 ; //从第一行第一个开始

lcd_enable ();

for ( i = 0 ; i < 16 ; i ++)

{

write ( welcome [ i ]);

}

}


- ---PWM 定时器- ---

#include

#include "HELLOPIC.h"

void main ()

{

TRISC= 0X00 ;

TRISB= 0X00 ;

TRISA= 0X00 ;

Timer0_Config ();

Timer1_Config ();

Timer2_Config ();

while ( 1 )

{

delayms ( 5 );

}

}

void interrupt timer ()

{

if (TMR2IF== 1 )

{

TMR2= 0x00 ;

TMR2IF= 0 ;

RB0=~RB0;

}

if (TMR1IF== 1 )

{

TMR1H=( 65535 - 5000 )/ 256 ;

TMR1L=( 65535 - 5000 )% 256 ;

TMR1IF= 0 ;

RB1=~RB1;

}

if (TMR0IF== 1 )

{

TMR0= 0x00 ;

TMR0IF= 0 ;

RB2=~RB2;

}

}


- --- 黑喂狗- ---

#include

#include "MAIN.h"

__CONFIG (LVPDIS & HS & PWRTDIS & BORDIS ); //设置配置位,使能看门狗

void main ()

{

TRISD= 0X00 ;

PORTD= 0XFF ;

delayms ( 500 );

while ( 1 )

{

PORTD= 0X00 ;

delayms ( 300 );

asm ( "clrwdt" ); //喂狗

}

}


- ---CCP 捕捉- ---

#include //包含单片机内部资源预定义

#define uchar unsigned char

#define uint unsigned int

#define s2 RA0

#define S3 RA1

__CONFIG ( 0xFF32 );

void usart_Config ()

{

TRISC= 0XFF ; //设置C口方向全为输出

SPBRG= 0XC ; //设置波特率为119200BPS

TXSTA= 0X24 ; //使能串口发送,选择高速波特率

RCSTA= 0X90 ; //使能串口工作,连续接收

RCIE= 0X1 ; //使能接收中断

}

void CCP_Config ()

{

//设置RC2为输入

CCP1CON= 0X05 ; //首先设置CCP1捕捉每个脉冲的上升沿

T1CON= 0X01 ; //关闭TMR1震荡器

PEIE= 1 ; //外围中断允许(此时总中断关闭)

PIE1= 0x05 ;

CCP1IF= 0 ;

TRISC2= 1 ;

CCPR1H= 0 ;

CCPR1L= 0 ;

}

void delay ()

{

int i;

for (;i< 30000 ;i++);

}

void main ()

{

TRISA= 0xfc ; //使能s2 s3引脚 设置其他脚为接收脚

TRISD= 0x00 ;

usart_Config ();

CCP_Config ();

int j;

while ( 1 )

{

delay ();

delay ();

}

}


void interrupt zhonduan ( void )

{

/* if(RCIE&&RCIF)            //判断是否为串口接收中断

{

TXREG=RCREG;           //把接收到的数据发送回去

}*/

if (CCP1IF== 1 )

{

TXREG=CCPR1H+ '0' ;

delay ();

delay ();

delay ();

delay ();

}

}


- --- 外部中断- ---

#include

#define uchar unsigned char

#define uint unsigned int

uint x ;

void init () //初始化中断 以及端口

{

//     OPTION=0x33;

INTCON= 0xb0 ;

TRISA= 0x10 ;

TRISD= 0x00 ;

TRISB= 0x01 ;

}

void main ()

{

init ();

while ( 1 );

}

void interrupt time0 ()

{

INTF= 0 ;

//  TMR0=253; //定时器装初值

PORTD=~PORTD;

}


- --- 串口- ---

#include //包含单片机内部资源预定义

__CONFIG ( 0xFF32 );

//芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡


/****************************************************************************

* 名    称:main()

* 功    能:主函数

* 入口参数:无

* 出口参数:无

* 说    明:无

****************************************************************************/

void main ()

{

TRISC= 0XFF ; //设置C口方向全为输出

SPBRG= 0XC ; //设置波特率为119200BPS

TXSTA= 0X24 ; //使能串口发送,选择高速波特率

RCSTA= 0X90 ; //使能串口工作,连续接收

RCIE= 0X1 ; //使能接收中断

GIE= 0X1 ; //开放全局中断

PEIE= 0X1 ; //使能外部中断

while ( 1 ) //等待中断

{;}

}

/****************************************************************************

* 名    称: usart()

* 功    能:中断函数

* 入口参数:

* 出口参数:

* 说    明:注意要有关键字 interrupt 如果是多种中断,在中断服务函数中,

要判断中断源标志

****************************************************************************/

void interrupt usart ( void )

{

if (RCIE&&RCIF) //判断是否为串口接收中断

{

TXREG=RCREG; //把接收到的数据发送回去

}

}


- ---ADC----

#include

#define uchar unsigned char

#define uint unsigned int

void init ()

{

int i;

TRISA= 0X01 ; //将RA0设置为模拟量输入端口

TRISD= 0x00 ;

PORTA= 0X00 ;

PORTD= 0X00 ;

ADCON0= 0x41 ; //选择通道0 选择分频 频率2us 开启adc电源

ADCON1= 0x8e ; //只有 ra0是模拟量输入

i= 1000 ;

while (i--);

}

uint getadc ()

{

uint leve;

ADGO= 1 ; //开启ad转换

while (ADGO) //等待ad转换完成

leve=ADRESL; //将adc的值给leve

PORTD=leve; //显示leve的值

}

void main ()

{

init ();

while ( 1 )

{

getadc ();

}

}


- --- 电子密码锁- ---

#include

#include "lcd.h"

uchar x , x1 , x2 , s1 , s2 , s3 , s4 ;

void displaywc ();

void displayps ();

uchar key ();

void writekey ();

void seekey ();

void main ()

{

init (); //调用I/O口初始化函数

lcd_init ();

displaywc ();

while ( 1 )

{

key ();

x1 = x ;

while ( x1 )

{

displayps ();

x1 = 1 ;

x = 0 ;

writekey ();

}

}

/*    write('a');

PORTD = 0XC0;           //设置第2行显示地址

lcd_enable();               //调用LCD显示设置函数

write('a');*/

}

/***************写入密码***********************/

void writekey ()

{

x = 0 ;

key ();

while (! key ());

s1 = x ;

PORTD = 0X80 + 0x40 ; //从第一行第一个开始

lcd_enable ();

write ( '0' + s1 );

x = 0 ;

key ();

while (! key ());

s2 = x ;

PORTD = 0X80 + 0x41 ; //从第一行第一个开始

lcd_enable ();

write ( '0' + s2 );

x = 0 ;

key ();

while (! key ());

s3 = x ;

PORTD = 0X80 + 0x43 ; //从第一行第一个开始

lcd_enable ();

write ( '0' + s3 );

x = 0 ;

key ();

while (! key ());

s4 = x ;

PORTD = 0X80 + 0x44 ; //从第一行第一个开始

lcd_enable ();

write ( '0' + s4 );

x = 0 ;

seekey ();

}

/**************密码正确错误检测***************/

void seekey ()

{

while (!( s1 == 1 ));

while (!( s2 == 2 ));

while (!( s3 == 3 ));

while (!( s4 == 4 ));

displaywc ();

while ( 1 );

}

/**************显示输入密码********************/

void displayps ()

{

uchar i ;

const uchar prd [] ={ "pass word write  " };

PORTD = 0X80 ; //从第一行第一个开始

lcd_enable ();

for ( i = 0 ; i < 16 ; i ++)

{

write ( prd [ i ]);

}

}

/*********************显示欢迎函数************************/

void displaywc ()

{

uchar i ;

const uchar welcome [] ={ "  welcome back  " };

PORTD = 0X80 ; //从第一行第一个开始

lcd_enable ();

for ( i = 0 ; i < 16 ; i ++)

{

write ( welcome [ i ]);

}

}

/*******************按键函数**************************/

uchar key ()

{

TRISB= 0X0f ; //选择行为输入列为输出

PORTB= 0X00 ; //列输出0行检测

if (RB0== 0 )

{

delay ( 10 );

if (RB0== 0 )

{

TRISB= 0Xf0 ;

PORTB= 0X00 ;

{

if (RB4== 0 )

{

while (!RB4);

x = 1 ;

}

if (RB5== 0 )

{

while (!RB5);

x = 2 ;

}

if (RB6== 0 )

{

while (!RB6);

x = 3 ;

}

if (RB7== 0 )

{

while (!RB7);

x = 4 ;

}

}

}

}

if (RB1== 0 )

{

delay ( 10 );

if (RB1== 0 )

{

TRISB= 0Xf0 ;

PORTB= 0X00 ;

{

if (RB4== 0 )

{

while (!RB4);

x = 5 ;

}

if (RB5== 0 )

{

while (!RB5);

x = 6 ;

}

if (RB6== 0 )

{

while (!RB6);

x = 7 ;

}

if (RB7== 0 )

{

while (!RB7);

x = 8 ;

}

}

}

}

if (RB2== 0 )

{

delay ( 10 );

if (RB2== 0 )

{

TRISB= 0Xf0 ;

PORTB= 0X00 ;

{

if (RB4== 0 )

{

while (!RB4);

x = 9 ;

}

if (RB5== 0 )

{

while (!RB5);

x = 10 ;

}

if (RB6== 0 )

{

while (!RB6);

x = 11 ;

}

if (RB7== 0 )

{

while (!RB7);

x = 12 ;

}

}

}

}

if (RB3== 0 )

{

delay ( 10 );

if (RB3== 0 )

{

TRISB= 0Xf0 ;

PORTB= 0X00 ;

{

if (RB4== 0 )

{

while (!RB4);

x = 13 ;

}

if (RB5== 0 )

{

while (!RB5);

x = 14 ;

}

if (RB6== 0 )

{

while (!RB6);

x = 15 ;

}

if (RB7== 0 )

{

while (!RB7);

x = 16 ;

}

}

}

}

return x ;

}


----LCD1602----

#include

#include "lcd.h"

void main ()

{

init (); //调用I/O口初始化函数

lcd_init ();


write ( 'a' );

PORTD = 0XC0 ; //设置第2行显示地址

lcd_enable (); //调用LCD显示设置函数

write ( 'a' );

while ( 1 );

}


lcd .c


#include "lcd.h"

void init ()

{

ADCON1 = 0X07 ; //设置A口为普通I/O口

RA1= 1 ;

TRISA = 0X00 ; //设置A口为输出

TRISD = 0X00 ; //设置D口为输出

}


void lcd_init ()

{

PORTD = 0X1 ; //清除显示

lcd_enable ();

PORTD = 0X38 ; //8位2行5*7点阵

lcd_enable ();

PORTD = 0X0c ; //显示开,光标开,闪烁

lcd_enable ();

PORTD = 0X06 ; //文字不动,光标右移

lcd_enable ();

PORTD = 0X80 ; //公司web显示地址

lcd_enable ();

}

void write ( char x )

{

PORTD = x; //待显示数据送PORTD口

rs = 1 ; //该字节数据为数据,而不是命令

rw = 0 ; //此次操作为写,而不是读

e = 0 ; //拉低使能信号

delay (); //保持使能信号为低一段时间

e = 1 ; //拉高使能信号,建立LCD操作所需要的上升沿

}

void lcd_enable ()

{

rs = 0 ; //该字节数据为命令,而不是数据

rw = 0 ; //此次操作为写,而不是读

e = 0 ; //拉低使能信号

delay (); //保持使能信号为低一段时间

e = 1 ; //拉高使能信号,建立LCD操作所需要的上升沿

}

void delay ()

{

int i;

for (i = 0 ;i < 5000 ;i++);}


lcd.h


#ifndef __lcd_H

#define __lcd_H


/**********************************

包含头文件

**********************************/

#include

//---重定义关键词---

#ifndef uchar

#define uchar unsigned char

#endif


#ifndef uint

#define uint unsigned int

#endif

/**********************************

PIN口定义

**********************************/

#define rs RA5

#define rw RA4

#define e  RA3

/**********************************

函数声明

**********************************/

void init (); //申明I/O口初始化函数

void lcd_init (); //申明LCD初始化函数

void write ( char x ); //申明显示1字节数据函数

void lcd_enable (); //申明LCD显示设置函数

void delay (); //申明延时函数

void wcmd ( char cmd ); //写指令

#endif


- --- 数码管- ---

#include

#define uchar unsigned char

#define uint unsigned int

uchar  shu [] ={ 0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08 };

void delay ();

void main ()

{

uchar i;

TRISD= 0x00 ; //设置成输出端口

TRISB= 0x00 ; //设置成输出端口

while ( 1 )

{

delay ();

delay ();

delay ();

PORTB= shu [i];

delay ();

delay ();

delay ();

i++;

if (i== 9 )i= 0 ;

}

}

void delay ()

{

int i; //定义整形变量

for (i = 10000 ;i--;); //延时

}


数码管动态显示

#include

#define uchar unsigned char

#define uint unsigned int

uchar  shu [] ={ 0xc0 , 0xf9 , 0xa4 , 0xb0 , 0x99 , 0x92 , 0x82 , 0xf8 , 0x80 , 0x90 , 0x88 , 0x83 , 0xc6 , 0xa1 , 0x86 , 0x8e };

void delay ();

void main ()

{

uchar i;

TRISD= 0x00 ; //设置成输出端口

TRISB= 0x00 ; //设置成输出端口

while ( 1 )

{

for (i= 0 ;i< 9 ;i++)

{

PORTD= 0X01 ;

PORTD=PORTD<

PORTD=~PORTD;

PORTB= shu [i];

delay ();


}

}

}

void delay ()

{

int i; //定义整形变量

for (i = 10000 ;i--;); //延时

}


- --- 点灯- ---

#include

#define uchar unsigned char

#define uint unsigned int

void delay ();

void main ()

{

TRISD= 0x00 ; //设置成输出端口

while ( 1 )

{

delay ();

delay ();

PORTD= 0XFF ;

delay ();

delay ();

}

}

void delay ()

{

int i; //定义整形变量

for (i = 10000 ;i--;); //延时

}



基齐了,兄弟们~

也算是咱们家电行业资深工程师了~

唯一的遗憾是没有玩过1块钱以下的 .

邮箱xutong @ zjbtie .com

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: TI培训

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved