|
|
  |
Как оценить время в Keil, Не могу посчитать количество тактов |
|
|
|
Mar 19 2010, 20:29
|

Местный
  
Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040

|
Цитата(Nikitoc @ Mar 19 2010, 17:27)  Я здесь вроде не читаю, а записываю... Ну как же: AT91C_BASE_PIOA -> PIO_CODR = AT91C_BASE_PIOA -> PIO_CODR | 0x00000800; Если подумать, откуда берётся значение выражения, выделенного жирным шрифтом?  Поэтому вполне достаточно будет просто: AT91C_BASE_PIOA -> PIO_CODR = 0x00000800; То же самое для PIO_SODR. Если записать в CODR 0x800 то установится в 0 только 11-й бит порта, на остальные никакого влияния не будет
|
|
|
|
|
Mar 19 2010, 20:37
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Nikitoc @ Mar 19 2010, 17:27)  Код AT91C_BASE_PIOA -> PIO_CODR = AT91C_BASE_PIOA -> PIO_CODR | 0x00000800 Я здесь вроде не читаю, а записываю... Как это сделать - на асме или на Си тоже можно? Читаете, естественно. Откуда иначе возьмется содержимое PIO_CODR, над которым производится операция bitwise OR? Если принять во внимание совершенную бесполезность чтения PIO_CODR (вредность, точнее, ибо никто даже не гарантирует, что из этого регистра будет считан 0, хотя на практике это и так), то останется: Код AT91C_BASE_PIOA->PIO_CODR = 0x00000800; И этот код даст точно такой же результат. P.S. Запись вида a |= 1 вместо a = a | 1 делает код гораздо более удобочитаемым.
|
|
|
|
|
Mar 19 2010, 22:45
|

Местный
  
Группа: Validating
Сообщений: 207
Регистрация: 14-01-09
Из: Днепропетровск
Пользователь №: 43 367

|
Огромное спасибо за пояснения уважаемым гуру. Я, видите ли, не силен в arm-ассемблере (в СИ тоже не профессор  ), знаю более-менее только микрочиповский, для 8-битников, но это совсем другое дело . С этим чтением запутался вообще. В общем сделал как вы рекомендовали и скомпилилось компактней: Код 0x00103C14 E3A01B02 MOV R1,#0x00000800 0x00103C18 E3A00000 MOV R0,#pI2C(0x00000000) 0x00103C1C E5001BD0 STR R1,[R0,#-0x0BD0] 3169: AT91C_BASE_PIOA -> PIO_CODR = 0x00000800; 0x00103C20 E5001BCC STR R1,[R0,#-0x0BCC] 0x00103C24 EAFFFFFC B 0x00103C1C здесь: Код AT91S_TWI * pI2C = AT91C_BASE_TWI; #define AT91C_BASE_TWI (AT91_CAST(AT91PS_TWI) 0xFFFB8000) // (TWI) Base Address Вроде бы (особенно с вашими разъяснениями) код стал понятен, кроме строки: Код 0x00103C18 E3A00000 MOV R0,#pI2C(0x00000000) Как я не отнимал от 0xFFFB8000 0x0BD0 и 0x0BCC, базовых адресов регистров PIO_CODR (0xFFFFF434) PIO_SODR (0xFFFFF430) я не получил  . Что я неправильно понимаю? Почему нельзя занести в регистр R0 значение не pI2C, а pPIO? Относительно него смещения были бы меньше.
Сообщение отредактировал Nikitoc - Mar 19 2010, 22:47
|
|
|
|
|
Mar 19 2010, 22:51
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Nikitoc @ Mar 20 2010, 01:45)  Вроде бы (особенно с вашими разъяснениями) код стал понятен, кроме строки: Код 0x00103C18 E3A00000 MOV R0,#pI2C(0x00000000) Как я не отнимал от 0xFFFB8000 0x0BD0 и 0x0BCC, базовых адресов регистров PIO_CODR (0xFFFFF434) PIO_SODR (0xFFFFF430) я не получил. Что я неправильно понимаю? Почему нельзя занести в регистр R0 значение не pI2C, а pPIO? Относительно него смещения были бы меньше. А почему от 0xFFFB8000, а не от 0, как, собственно, и написано в команде? 0 - 0x0BD0 = 0xFFFFF430; 0 - 0x0BCC = 0xFFFFF434 Откуда в листинге взялся pI2C - остается только гадать. Вполне допускаю, что это просто своеобразный глюк дизассемблера.
|
|
|
|
|
Apr 6 2010, 15:59
|

Местный
  
Группа: Validating
Сообщений: 207
Регистрация: 14-01-09
Из: Днепропетровск
Пользователь №: 43 367

|
Продолжаю терзать at91sam7s256. Привожу код который я написал для работы с SPI. Самое удивительное (для меня) и чему я не могу найти объяснения - это то, что код этот нормально работал (писал на SD-карточку), а теперь перестал работать. Код ///////////////////////////////////////////////////////////////////////////// void CONFIG_SPI () { pSPI -> SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | (AT91C_SPI_PCS & (0x0D << 16)); //Master mode, use freq divider, select 1 chanel CS. pSPI -> SPI_CSR[1] = AT91C_SPI_NCPHA | AT91C_SPI_BITS_8 | AT91C_SPI_CSAAT | (AT91C_SPI_SCBR & (SCBR << 8)); // clock idle low, data valid on rising edge, 8-bit data pSPI -> SPI_CR = AT91C_SPI_SPIEN | AT91C_SPI_LASTXFER; } ///////////////////////////////////////////////////////////////////////////////////// char SPI (char DATA) { pSPI -> SPI_TDR = DATA; while (!(pSPI -> SPI_SR & AT91C_SPI_TDRE)); /* Wait for Empty Tx Buffer */ while (!(pSPI -> SPI_SR & AT91C_SPI_RDRF)); return (pSPI -> SPI_RDR & 0xFF); } //////////////////////////////////////////////////////////////////////////////////// Просьба помочь найти ошибку.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|