烧写了attiny9程序,感觉总是不正常,好像根本没有跑起来,有高手指点一二吗?
#define F_CPU 4000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include <avr/interrupt.h>
#define uchar unsigned char
#define uint unsigned int
#define write_ADD 0x88
#define read_ADD 0x89
#define CONF_ADDR 0x01
#define INTER_ADDR 0x02
#define PROX_LT 0x03
#define PROX_HT 0x04
#define PROX_DATA 0x08
#define CONF_PROXREG 0xA8//prox sensor is enable and the sleep time is 200ms(1010 1000)
#define CONF_INTREG 0x00
#define I2C_SDA_OUT DDRB |= (1 << PORTB3)
#define I2C_SDA_IN DDRB &= ~(1 << PORTB3)
#define I2C_SCL_OUT DDRB |= (1 << PORTB0)
#define I2C_SCL_IN DDRB &= ~(1 << PORTB0)
#define SDA_WRT_H PORTB |= (1 << PORTB3)
#define SDA_WRT_L PORTB &= ~(1 << PORTB3)
#define SCL_WRT_H PORTB |= (1 << PORTB0)
#define SCL_WRT_L PORTB &= ~(1 << PORTB0)
#define ALERT_ON PORTB |= (1 << PORTB2)
#define ALERT_OFF PORTB &= ~(1 << PORTB2)
//#define SDA_RED_H (PINB0 == 1)
#define SDA_READ PINB3
void init_sys(void);
void I2c_init(); //初始化
uchar I2c_respond(); //应答 SCL在高电平期间,SDA被从设备拉为低电平表示应答
void I2c_ACK(void);
void I2c_Start(void);
void I2c_Stop(void);
uchar I2c_write_byte(uchar dat);//写字节
void I2c_write(uchar addr,uchar dat); //指定地址写
uchar I2c_read_byte(void); //读字节
uchar I2c_read(uchar addr); //指定地址读
uchar g_bflag = 0; //应答标志位
uchar g_ProxVal = 0; //接近程度值
uchar g_proxH = 0xFF; //接近度报警值
uint g_iTimebase = 0xFF;
void Conf_reg(void);
void SetProxVal(uchar prox_h, uchar prox_l);
void IsAlert(void);
//定时器初始化
void Timer_Init();
void Timer_changeMs(uchar ms100);//unit:100 ms
void SetSleepMode(uchar ms100);//unit:100ms
//定时器初始化
void Timer_Init()
{
TCCR0B = 0x05; //预分频1024
g_iTimebase = F_CPU / 1024.0 * 0.1;//0.1s
//Timer_changeMs(2);//0.2s中断
}
void Timer_changeMs(uchar ms100)
{
//max is 16s
if(ms100 > 160)
ms100 = 160;
uint uTimes = g_iTimebase * ms100;
TCNT0L = 256 - (uTimes & 0xFF); //
TCNT0H = 256 - ((uTimes >> 8) & 0xFF);
TIMSK0 = 0x01; //使能T0中断
//sei(); //开中断
}
ISR(TIM0_OVF_vect)
{
}
void SetSleepMode(uchar ms100)
{
cli(); //disable all interrupts
Timer_changeMs(ms100);
sei(); //开中断
}
void init_sys(void)
{
//BBMB = 1;//break-before-make:pin input to output
PORTCR = 0x01;
I2C_SDA_OUT;
I2C_SCL_OUT;
}
//***************************************************************************
////开始信号
//在时钟线SCL为高电平时,数据线SDA由高向低跳变.
void I2c_Start()
{
SDA_WRT_H;
SCL_WRT_H;
_delay_us(5);
//SDA = 0;
SDA_WRT_L;
_delay_us(5);
//SCL = 0;
SCL_WRT_L;
_delay_us(5);
}
//***************************************************************************
void I2c_Stop() //停止 SCL在高电平期间,SDA一个上升沿则表示停止信号
{
SDA_WRT_L;
_delay_us(5);
SCL_WRT_H;
_delay_us(5);
SDA_WRT_H;
}
//***************************************************************************
uchar I2c_respond() //应答 SCL在高电平期间,SDA被从设备拉为低电平表示应答
{
uchar ACK = 0;
SDA_WRT_H;
SCL_WRT_H;
I2C_SDA_IN;
_delay_us(5);
ACK = ~SDA_READ;//?
SCL_WRT_L;
_delay_us(5);
I2C_SDA_OUT;
return ACK;
}
//***************************************************************************
void I2c_init()//总线初始化 将总线都拉高一释放总线 发送启动信号前,要先初始化总线。即总有检测到总线空闲才开始发送启动信号
{
//SDA = 1;
SDA_WRT_H;
_delay_us(5);
//SCL = 1;
SCL_WRT_H;
_delay_us(5);
}
//***************************************************************************
uchar I2c_write_byte(uchar dat) //写一个字节
{
uchar i;
for(i = 0; i < 8; i++)
{
if(((dat << i) & 0x80) > 0)
{
SDA_WRT_H;
}
else
{
SDA_WRT_L;
}
//SCL = 1;
SCL_WRT_L;
_delay_us(5);
//SCL = 0;
SCL_WRT_L;
_delay_us(5);
}
//发送一个字节后,读取来自I2C芯片的响应.
//即在发送完8个字节后,在第九个时钟内,SDA总线应为低电平,表示I2C芯片已经读取了数据.
//否则为高电平.即发送败.
return I2c_respond();
}
//***************************************************************************
uchar I2c_read_byte(void)//读一个字节
{
uchar i,k = 0;
//SDA = 1;
SDA_WRT_H;
I2C_SDA_IN;
for(i = 0; i < 8; i++)
{
SCL_WRT_H;
//SCL = 1;//上升沿时,IIC设备将数据放在sda线上,并在高电平期间数据已经稳定,可以接收啦
_delay_us(5);
k = (k << 1) | SDA_READ;
//SCL = 0;//拉低SCL,使发送端可以把数据放在SDA上
SCL_WRT_L;
_delay_us(5);
}
return k;
}
//***************************************************************************
void I2c_write(uchar addr, uchar dat)//任意地址写一个字节
{
I2c_Start();//启动
I2c_write_byte(write_ADD);//发送从设备地址
I2c_respond();//等待从设备的响应
I2c_write_byte(addr);//发出芯片内地址
I2c_respond();//等待从设备的响应
I2c_write_byte(dat);//发送数据
I2c_respond();//等待从设备的响应
I2c_Stop();//停止
}
//***************************************************************************
uchar I2c_read(uchar addr)//读取一个字节
{
uchar dat;
I2c_Start();//启动
I2c_write_byte(write_ADD);//发送从设备地址 写操作
I2c_respond();//等待从设备的响应
I2c_write_byte(addr);//发送芯片内地址
I2c_respond();//等待从设备的响应
I2c_Start();//启动
I2c_write_byte(read_ADD);//发送从设备地址 读操作
I2c_respond();//等待从设备的响应
dat = I2c_read_byte();//获取数据
I2c_Stop();//停止
return dat;//返回数据
}
void Conf_reg(void)
{
uchar prox_l = 25;//FSR10%
uchar prox_h = 50;//FSR20%
uchar prox_max = 100;//FSR40%
I2c_write(CONF_ADDR, CONF_PROXREG);//prox sensor enable and sleep mode 200ms
I2c_write(INTER_ADDR, 0);
prox_h = I2c_read(PROX_DATA);
if(prox_h < prox_max && prox_h > prox_l)
{
prox_l = prox_h;
}
g_ProxVal = prox_l << 1;
I2c_write(PROX_LT, prox_l);
I2c_write(PROX_HT, g_ProxVal);
}
int main(void)
{
uchar prox_data = 0;
//_delay_ms(1000);
init_sys();
I2c_init();
Conf_reg();
while(1)
{
//TODO:: Please write your application code
prox_data = I2c_read(PROX_DATA);
if(prox_data >= g_ProxVal)
{
ALERT_ON;
//_delay_ms(5000);
SetSleepMode(50);//5s
}
//_delay_ms(205);
ALERT_OFF;
SetSleepMode(2);//0.2s
}
}
|