0

我是 C 的初学者。我正在尝试写入和读取外部 eeprom (AT24c02B),然后将存储在 eeprom 中的数据字节显示到 PORTB 中的 LED 和/或 LCD。所以我知道数据成功存储在eeprom中。

PORTB 中的 LED 低电平有效。

这是代码,我从 cvAVR 帮助中获得的:

#include <mega16a.h>

// Alphanumeric LCD functions
#include <alcd.h>

// Declare your global variables here

// TWI functions
#include <twi.h>

#include <delay.h>

/* 7 bit TWI bus slave address of the AT24C02B 2kbyte EEPROM */
#define EEPROM_TWI_BUS_ADDRESS (0xA0 >> 1)

void main(void)
{
// Declare your local variables here
struct
     {
     struct
          {
          unsigned char msb;
          unsigned char lsb;
          } addr;
     unsigned char data;
     } twi_eeprom;


unsigned char eeprom_rd_data;

// Input/Output Ports initialization
// Port A initialization
// Function: Bit7=Out Bit6=Out Bit5=Out Bit4=Out Bit3=Out Bit2=Out Bit1=Out Bit0=Out 
DDRA=(1<<DDA7) | (1<<DDA6) | (1<<DDA5) | (1<<DDA4) | (1<<DDA3) | (1<<DDA2) | (1<<DDA1) | (1<<DDA0);
// State: Bit7=0 Bit6=0 Bit5=0 Bit4=0 Bit3=0 Bit2=0 Bit1=0 Bit0=0 
PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) | (0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);

// Port B initialization
// Function: Bit7=Out Bit6=Out Bit5=Out Bit4=Out Bit3=Out Bit2=Out Bit1=Out Bit0=Out 
DDRB=(1<<DDB7) | (1<<DDB6) | (1<<DDB5) | (1<<DDB4) | (1<<DDB3) | (1<<DDB2) | (1<<DDB1) | (1<<DDB0);
// State: Bit7=1 Bit6=1 Bit5=1 Bit4=1 Bit3=1 Bit2=1 Bit1=1 Bit0=1 
PORTB=(1<<PORTB7) | (1<<PORTB6) | (1<<PORTB5) | (1<<PORTB4) | (1<<PORTB3) | (1<<PORTB2) | (1<<PORTB1) | (1<<PORTB0);

// TWI initialization
// Mode: TWI Master
// Bit Rate: 100 kHz
twi_master_init(100);

// Alphanumeric LCD initialization
// Connections are specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTA Bit 0
// RD - PORTA Bit 1
// EN - PORTA Bit 2
// D4 - PORTA Bit 4
// D5 - PORTA Bit 5
// D6 - PORTA Bit 6
// D7 - PORTA Bit 7
// Characters/line: 16
lcd_init(16);

// Global enable interrupts
#asm("sei")

/* write the byte 0x55 to the AT24C02B EEPROM address 0x210 */
twi_eeprom.addr.msb=0x02;
twi_eeprom.addr.lsb=0x10;
twi_eeprom.data=0x55;
twi_master_trans(EEPROM_TWI_BUS_ADDRESS,(unsigned char *) &twi_eeprom,3,0,0);

/* 10ms delay to complete the write operation */
delay_ms(10);

/* read the byte back into the eeprom_rd_data variable */
twi_master_trans(EEPROM_TWI_BUS_ADDRESS,(unsigned char *) &twi_eeprom,2,&eeprom_rd_data,1);

while (1)
      {
      // Place your code here

      PORTB = ; //What variable should I call?
      delay_ms(3000);
      }
}  

tw.h

/******************************************************************************
 TWI driver library for the CodeVisionAVR C V2.05.1+ Compiler

 Copyright (C) 2010-2011 Pavel Haiduc, HP InfoTech S.R.L., All rights reserved.
*******************************************************************************/

#ifndef _TWI_INCLUDED_
#define _TWI_INCLUDED_

#include <stdbool.h>

// TWI transaction result values
#define TWI_RES_OK 0
#define TWI_RES_BUFFER_OVERFLOW 1
#define TWI_RES_ARBITRATION_LOST 2
#define TWI_RES_BUS_ERROR 3
#define TWI_RES_NACK_RECEIVED 4
#define TWI_RES_BUS_TIMEOUT 5
#define TWI_RES_FAIL 6
#define TWI_RES_UNKNOWN 7

extern unsigned char twi_tx_index; // data index in the transmit buffer
extern unsigned char twi_rx_index; // data index in the receive buffer
extern unsigned char twi_result; // holds the result of the last TWI transaction

// TWI master initialization
// bit_rate - SCL bit rate [kHz]
void twi_master_init(unsigned int bit_rate);

// function used for performing a TWI master transaction
// slave_addr - 7 bit address of the TWI slave with which the transaction must be performed
// tx_data - pointer to the buffer that holds the data to be transmitted to the slave
// tx_count - number of bytes that must be transmitted to the slave during the transaction
// rx_data - pointer to the buffer that holds the data received from the slave
// rx_count - number of bytes that must be received from the slave during the transaction
// returns true on success
bool twi_master_trans(
     unsigned char slave_addr,
     unsigned char *tx_data, unsigned char tx_count,
     unsigned char *rx_data, unsigned char rx_count);

// TWI slave initialization
// match_any_addr - if true, the slave match address logic responds to all received addresses
// addr - 7 bit address of the TWI slave
// rx_buffer - pointer to the slave receive buffer
// rx_buffer_size - size of the slave receive buffer
// tx_buffer - pointer to the slave transmit buffer
// slave_rx_handler - pointer to the TWI slave receive processing function
// slave_tx_handler - pointer to the TWI slave transmit processing function
void twi_slave_init(
     bool match_any_addr,
     unsigned char addr,
     unsigned char *rx_buffer,
     unsigned char rx_buffer_size,
     unsigned char *tx_buffer,
     bool (*slave_rx_handler)(bool rx_complete),
     unsigned char (*slave_tx_handler)(bool tx_complete)
     );

#pragma library twi.lib

#endif

我想问的是:
1.写入eeprom后,我应该调用什么变量来显示8个LED上的字节?

例如:写入字节后:0xF0,则 PORTB 中的 LED 将为 0xF0 (11110000)

  1. 我确实在互联网上搜索过,但仍然对这条线感到困惑

twi_master_trans(EEPROM_TWI_BUS_ADDRESS,(unsigned char *) &twi_eeprom,3,0,0);

twi_master_trans(EEPROM_TWI_BUS_ADDRESS,(unsigned char *) &twi_eeprom,2,&eeprom_rd_data,1);

有人可以解释一下吗?实际上是什么&twi_eeprom,3,0,0意思?

设备:Atmega16a
程序:Codevision AVR 3.12
外部 eeprom:AT24c02b

Any answer and comment would be appreciate.
Thanks and pardon my english.

Ipin

4

1 回答 1

0

TWI is a method for transferring data both ways from a master device to a slave device. In your case, your code runs on the master, and the EEPROM is the slave. The data moves between the devices at the same time. That is, a byte is transferred to the slave simultaneously to a byte being transferred back from the slave.

The functions given in twi.h describe a way to start this process, and the parameters are described there.

unsigned char slave_addr,
unsigned char *tx_data, 
unsigned char tx_count,
unsigned char *rx_data, 
unsigned char rx_count

The first parameter is a constant given in your code.

The next two params are the address of the buffer to take data from and the length to take.

The next two are the address of the buffer to put the received data into, and the length.

To write 0x55 to the EEPROM at a specific address, you need to send three bytes to the EEPROM. These are arranged in a struct for you. If you give the function the address of the struct and the length 3, the function will take care of it for you. (unsigned char *) &twi_eeprom is the address of the struct.

You don't care about receiving right now, so just put in 0 and 0 for the address and length to receive.

When you read back the value, you only need to send the address of the byte to the EEPROM. So send the same struct, but only two bytes of it. You also need to save the received byte. It will go into the variable eeprom_rd_data, since you passed the address of that variable into the function. Set PORRTB to equal eeprom_rd_data to display its value.

于 2015-05-24T01:16:22.343 回答