⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 function.c

📁 gcc写的mega128的串口和twi程序
💻 C
字号:
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <util/twi.h>

#include "function.h"
//******************************************************************************
//*******************************delay*****************************************/
//******************************************************************************
void delay_us(unsigned int time)
{//短延时time(us)//
	unsigned int i;
	for(i=0;i<time;i++)
	_delay_us(1);
}
void delay_ms(unsigned int time)
{//长延时time(ms)//
	unsigned int i;
	for(i=0;i<time;i++)
	_delay_ms(1);
}
//******************************************************************************
//*******************************USART FUNCFION********************************/
//******************************************************************************
void Usart_Init(unsigned char com_num,unsigned long baud_rate,unsigned char data_bit,unsigned char stop_bit,unsigned char check_bit)
{//usart串口初始化//端口,波特率,数据位,停止位,校验位
	unsigned long	baud[8]={4800,9600,14400,19200,28800,38400,57600,115200};
	unsigned char 	baud_set[8]={207,103,68,51,34,25,16,8};
	unsigned char	i;
	for(i=0;i<8;i++)
	{
		if(baud_rate==baud[i])		break;
	}
	switch(com_num)
	{
		case 0:			
			UCSR0B = 0X00;//USART工作前先停止USART工作
			UCSR0A = 0X00;//传输倍率1倍
			//配置串口通信///////////////////////////////////////////
			bitset(UCSR0C,7);
			bitclr(UCSR0C,UMSEL0);//异步传输
			switch(check_bit)
			{
				case 0:
					bitclr(UCSR0C,UPM00);//
					bitclr(UCSR0C,UPM01);//无校验
					break;
				case 1:
					bitset(UCSR0C,UPM00);
					bitset(UCSR0C,UPM01);//奇校验
					break;					
				case 2:
					bitclr(UCSR0C,UPM00);
					bitset(UCSR0C,UPM01);//偶检验
					break;						
			}
			switch(stop_bit)
			{
				case 1:
					bitclr(UCSR0C,USBS0);//1位停止位
					break;
				case 2:
					bitset(UCSR0C,USBS0);//2位停止位
					break;
			}
			switch(data_bit)
			{
				case 5:
					bitclr(UCSR0C,UCSZ00);
					bitclr(UCSR0C,UCSZ01);//5位数据位
					break;
				case 6:
					bitset(UCSR0C,UCSZ00);
					bitclr(UCSR0C,UCSZ01);//6位数据位
					break;
				case 7:
					bitclr(UCSR0C,UCSZ00);
					bitset(UCSR0C,UCSZ01);//7位数据位
					break;
				case 8:
					bitset(UCSR0C,UCSZ00);
					bitset(UCSR0C,UCSZ01);//8位数据位
					break;
			}
			bitclr(UCSR0C,UCPOL0);		  //异步通信时将此位置为0
			//配置串口通信///////////////////////////////////////////
			// 设置帧格式: 异步8个数据位1个停止奇校验
			//UCSR0C = 0x36;//B00110110
			// 设置波特率
			UBRR0H = 0X00;
			UBRR0L = baud_set[i];
			// 接收器与发送器使能
			UCSR0B = (1<<RXEN0)|(1<<TXEN0);
			break;
		case 1:	
			UCSR1B = 0X00;//USART工作前先停止USART工作
			UCSR1A = 0X00;//传输倍率1倍
			//配置串口通信///////////////////////////////////////////
			bitset(UCSR1C,7);
			bitclr(UCSR1C,UMSEL1);//异步传输
			switch(check_bit)
			{
				case 0:
					bitclr(UCSR1C,UPM10);//
					bitclr(UCSR1C,UPM11);//无校验
					break;
				case 1:
					bitset(UCSR1C,UPM10);
					bitset(UCSR1C,UPM11);//奇校验
					break;					
				case 2:
					bitclr(UCSR1C,UPM10);
					bitset(UCSR1C,UPM11);//偶检验
					break;						
			}
			switch(stop_bit)
			{
				case 1:
					bitclr(UCSR1C,USBS1);//1位停止位
					break;
				case 2:
					bitset(UCSR1C,USBS1);//2位停止位
					break;
			}
			switch(data_bit)
			{
				case 5:
					bitclr(UCSR1C,UCSZ10);
					bitclr(UCSR1C,UCSZ11);//5位数据位
					break;
				case 6:
					bitset(UCSR1C,UCSZ10);
					bitclr(UCSR1C,UCSZ11);//6位数据位
					break;
				case 7:
					bitclr(UCSR1C,UCSZ10);
					bitset(UCSR1C,UCSZ11);//7位数据位
					break;
				case 8:
					bitset(UCSR1C,UCSZ10);
					bitset(UCSR1C,UCSZ11);//8位数据位
					break;
			}
			bitclr(UCSR1C,UCPOL1);		  //异步通信时将此位置为0
			//配置串口通信///////////////////////////////////////////
			//设置帧格式: 异步8个数据位1个停止奇校验
			//UCSR1C = 0x36;//B00110110
			//设置波特率
			UBRR1H = 0X00;
			UBRR1L = baud_set[i];
			// 接收器与发送器使能
			UCSR1B = (1<<RXEN1)|(1<<TXEN1);
			break;
	}
	//UDR0=0x00;
}

void Usart_Send(unsigned char com_num,unsigned char data)
{//usart串口发送
	switch(com_num)
	{	
		case 0:		
			/* 等待发送缓冲器为空 */
			while ( !( UCSR0A & (1<<UDRE0)) )
			;
			/* 将数据放入缓冲器,发送数据*/
			UDR0 = data;
			break;
		case 1:		
			/* 等待发送缓冲器为空 */
			while ( !( UCSR1A & (1<<UDRE1)) )
			;
			/* 将数据放入缓冲器,发送数据*/
			UDR1 = data;
			break;
	}
}
unsigned char Usart0_Receive(void)
{//串口0接收
	unsigned char receive_temp=0;
	if(UCSR0A & (1<<RXC0))
		receive_temp=UDR0;
	return receive_temp;
}
unsigned char Usart1_Receive(void)
{//串口1接收
	unsigned char receive_temp=0;
	if(UCSR1A & (1<<RXC1))
		receive_temp=UDR1;
	return receive_temp;
}
unsigned char Usart_Receive(void)
{//usart串口接收
	unsigned char receive_temp;
	receive_temp=Usart0_Receive();
	if(receive_temp)	return	receive_temp;
	receive_temp=Usart1_Receive();
	if(receive_temp)	return	receive_temp;
	return 0;
}
//******************************************************************************
//*******************************TWI FUNCTION**********************************/
//******************************************************************************
void Twi_Init(void)
{//Twi口初始化
  /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */
  TWSR = 0;
  TWBR = (F_CPU / 100000UL - 16) / 2;
}
int ee24xx_read_bytes(uint16_t eeaddr, int len, uint8_t *buf)
{//读EEPROM
  uint8_t sla, twcr, n = 0;
  int rv = 0;

	
  /* patch high bits of EEPROM address into SLA */
  sla = TWI_SLA_24CXX | (((eeaddr >> 8) & 0x07) << 1);

  /*
   * Note [8]
   * First cycle: master transmitter mode
   */
  restart:
	  
  if (n++ >= MAX_ITER)
    return -1;
  begin:
	
  TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* send start condition */
  while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
  switch ((twst = TW_STATUS))
    {
    case TW_REP_START:		/* OK, but should not happen */
    case TW_START:
      break;

    case TW_MT_ARB_LOST:	/* Note [9] */
      goto begin;

    default:
      return -1;		/* error: not in start condition */
				/* NB: do /not/ send stop condition */
    }

  /* Note [10] */
  /* send SLA+W */
  TWDR = sla | TW_WRITE;
  TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
  while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
  switch ((twst = TW_STATUS))
    {
    case TW_MT_SLA_ACK:
      break;

    case TW_MT_SLA_NACK:	/* nack during select: device busy writing */
				/* Note [11] */
      goto restart;

    case TW_MT_ARB_LOST:	/* re-arbitrate */
      goto begin;

    default:
      goto error;		/* must send stop condition */
    }

  TWDR = eeaddr;		/* low 8 bits of addr */
  TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
  while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
  switch ((twst = TW_STATUS))
    {
    case TW_MT_DATA_ACK:
      break;

    case TW_MT_DATA_NACK:
      goto quit;

    case TW_MT_ARB_LOST:
      goto begin;

    default:
      goto error;		/* must send stop condition */
    }

  /*
   * Note [12]
   * Next cycle(s): master receiver mode
   */
  TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* send (rep.) start condition */
  while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
  switch ((twst = TW_STATUS))
    {
    case TW_START:		/* OK, but should not happen */
    case TW_REP_START:
      break;

    case TW_MT_ARB_LOST:
      goto begin;

    default:
      goto error;
    }

  /* send SLA+R */
  TWDR = sla | TW_READ;
  TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
  while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
  switch ((twst = TW_STATUS))
    {
    case TW_MR_SLA_ACK:
      break;

    case TW_MR_SLA_NACK:
      goto quit;

    case TW_MR_ARB_LOST:
      goto begin;

    default:
      goto error;
    }

  for (twcr = _BV(TWINT) | _BV(TWEN) | _BV(TWEA) /* Note [13] */;
       len > 0;
       len--)
    {
      if (len == 1)
	twcr = _BV(TWINT) | _BV(TWEN); /* send NAK this time */
      TWCR = twcr;		/* clear int to start transmission */
      while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
      switch ((twst = TW_STATUS))
	{
	case TW_MR_DATA_NACK:
	  len = 0;		/* force end of loop */
	  /* FALLTHROUGH */
	case TW_MR_DATA_ACK:
	  *buf++ = TWDR;
	  rv++;
	  break;

	default:
	  goto error;
	}
    }
  quit:
  /* Note [14] */
  TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN); /* send stop condition */

  return rv;

  error:
  rv = -1;
  goto quit;
}
int ee24xx_write_bytes(uint16_t eeaddr, int len, uint8_t *buf)
{//写EEPROM
  uint8_t sla, n = 0;
  int rv = 0;
  uint16_t endaddr;
	
//  if (eeaddr + len < (eeaddr | (PAGE_SIZE - 1)))
//    endaddr = eeaddr + len;
//  else
//    endaddr = (eeaddr | (PAGE_SIZE - 1)) + 1;
//  len = endaddr - eeaddr;

endaddr=eeaddr+len-1;
  /* patch high bits of EEPROM address into SLA */
  sla = TWI_SLA_24CXX | (((eeaddr >> 8) & 0x07) << 1);

  restart:
	  
  if (n++ >= MAX_ITER)
    return -1;
  begin:
	
  /* Note [15] */
  TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* send start condition */
  while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
  switch ((twst = TW_STATUS))
    {
    case TW_REP_START:		/* OK, but should not happen */
    case TW_START:
      break;

    case TW_MT_ARB_LOST:
      goto begin;

    default:
      return -1;		/* error: not in start condition */
				/* NB: do /not/ send stop condition */
    }

  /* send SLA+W */
  TWDR = sla | TW_WRITE;
  TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
  while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
  switch ((twst = TW_STATUS))
    {
    case TW_MT_SLA_ACK:
      break;

    case TW_MT_SLA_NACK:	/* nack during select: device busy writing */
      goto restart;

    case TW_MT_ARB_LOST:	/* re-arbitrate */
      goto begin;

    default:
      goto error;		/* must send stop condition */
    }

  TWDR = eeaddr;		/* low 8 bits of addr */
  TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
  while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
  switch ((twst = TW_STATUS))
    {
    case TW_MT_DATA_ACK:
      break;

    case TW_MT_DATA_NACK:
      goto quit;

    case TW_MT_ARB_LOST:
      goto begin;

    default:
      goto error;		/* must send stop condition */
    }

  for (; len > 0; len--)
    {
      TWDR = *buf++;
      TWCR = _BV(TWINT) | _BV(TWEN); /* start transmission */
      while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
      switch ((twst = TW_STATUS))
	{
	case TW_MT_DATA_NACK:
	  goto error;		/* device write protected -- Note [16] */

	case TW_MT_DATA_ACK:
	  rv++;
	  break;

	default:
	  goto error;
	}
    }
  quit:
  TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN); /* send stop condition */

  return rv;

  error:
  rv = -1;
  goto quit;
}
//******************************************************************************
//*******************************内部EEPROM*************************************/
//******************************************************************************
unsigned char EEPROM_read(unsigned int uiAddress)
{//写内部EEPROM
	while(EECR & (1<<EEWE))	//等待上一次写操作结束
	;	
	EEAR = uiAddress;			//设置地址寄存器	
	EECR |= (1<<EERE);			//设置EERE以启动读操作
	return EEDR;				//自数据寄存器返回数据
}
void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
{//读内部EEPROM
	while(EECR & (1<<EEWE))	//等待上一次写操作结束
	;	
	EEAR = uiAddress;			//设置地址和数据寄存器
	EEDR = ucData;
	EECR |= (1<<EEMWE);		//置位EEMWE
	EECR |= (1<<EEWE);			//置位EEWE以启动写操作E
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -