Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.



Интерфейсы: UART, I2C

Сообщений 1 страница 12 из 12

1

Не знаю: Смеяться или плакать
Неделю пытал встроенные аппаратные UART 1 и 2, а именно PRINT средствами самого БАСКОМ...
Уже и дизассемблер применил, и регистры уже скоро буду без справочников читать в hex ))))

Всё оказалось куда веселее ))) Логики не вижу. Но факт остаётся!
А заработало тогда, когда я включил резисторы pull-up! )))
PS: Всё еще интереснее: Кривой перевод ОДНОГО СЛОВА в даташите у китайцев. Надо было перевести как "pin", а написано "input"
Чтобы не включать подтяжку, надо ПРАВИЛЬНО инициализировать порт :)
А именно: Если вывод МК применяем НЕ как аналоговый вход, Т.Е, как цифровой, то в нужном бите УСТАНОВИТЬ 1

Работают ОБА UART на нужных мне ногах
Но все на одной скорости!

После инициализации (ручками + Bascom) надо что-то записать в буфер UART1 и UART2 - без этой магии не хочет!

https://forumupload.ru/uploads/0000/25/b8/439/t980499.jpg

Код:
$regfile = "STC_8H.DAT"                   ' STC registers list
$crystal = 11059200                       ' CPU clock frequence

My_led Alias P3.5

P1ie = &B1111_1111                        ' 1: Enable digital signal
P1pu = &B0000_0000                        ' 1: pull-up resistor
P1m1 = &B_0000_0000 : P1m0 = &B_1010_0010       ' Push-pull output mode

P3ie = &B1111_1111                        ' 1: Enable digital signal
P3pu = &B0000_0000                        ' 1: pull-up resistor
P3m1 = &B0000_0000 : P3m0 = &B_1000_0010       ' Push-pull output mode

Scon = &H50                               ' 1010000  8 bits and variable baudrate
S2con = &H10                              ' 0010000

T2l = &HE8                                ' Initial value Timer2 115200
T2h = &HFF

'Auxr = &H14                              '0001_0100  UART1
Auxr = &H15                               '0001_0101  UART 1 + 2

P_sw1 = &H00                              'RXD/P3.0, TXD/P3.1
'P_sw1 = &H40                              'RXD_2/P3.6, TXD_2/P3.7
'P_sw1 = &H80                              'RXD_3/P1.6, TXD_3/P1.7
'P_sw1 = &HC0                              'Rxd_4/P4.3, Txd_4/P4.4

P_sw2 = &H00                              'RXD2/P1.0, TXD2/P1.1
'P_sw2 = &H01                              'RXD2_2/P4.6, TXD2_2/P4.7

Dim Temp As Byte


Open "COM2:" For Binary As #1             ' Откроем второй UART

 Sbuf = 0                                 ' 1  Зачем - не знаю.
 S2buf = 0                                ' 2  Но без этого не работает


Do

 If My_led = 1 Then                       ' Мигаем
   My_led = 0
  Else
   My_led = 1
 End If



 Print "1 Hello! Привет! " ; Temp  
 Print #1 , "2 Hello! Привет! " ; Temp 

 Print "1 1234 " ; Chr(temp)  
 Print #1 , "2 1234 " ; Chr(temp)

 Print "1 asdfg"                
 Print #1 , "2 asdfg"          


 Waitms 150
 Incr Temp

Loop
Close #1

Отредактировано Александр Д. (2024-05-02 20:46:04)

0

2

Каждому UART - своя скорость
1 = 9600
2 = 115200

Как настроил - не знаю )) Еще не все биты в регистрах выучил и понял

Да, для работы UART надо задействовать таймер!
Два UART = два таймера :(
Как-то печально...

PS:
Input и InputBin работают (по крайней мере, на Uart1)
главное настроить порт и сам UART

Код:
$regfile = "STC_8H.DAT"                   ' STC registers list
$crystal = 11059200                       ' CPU clock frequence
$ramsize = &H400                          ' 1024
$romstart = &H0                           ' code starting address

Dim Temp As Byte
Dim Mstr$ As String * 16

Mstr$ = "Привет всем!"


My_led Alias P3.5

P1ie = &B1111_1111                        ' 1: Enable digital pins
P1pu = &B0000_0000                        ' 1: pull-up resistor
P1m1 = &B_0000_0000 : P1m0 = &B_1010_0010       ' Push-pull output mode

P3ie = &B1111_1111                        ' 1: Enable digital pins
P3pu = &B0000_0000                        ' 1: pull-up resistor
P3m1 = &B0000_0000 : P3m0 = &B_1000_0010       ' Push-pull output mode


' Установим выводы для двух UART
P_sw1 = &H00                              'RXD/P3.0, TXD/P3.1
'P_sw1 = &H40                              'RXD_2/P3.6, TXD_2/P3.7
'P_sw1 = &H80                              'RXD_3/P1.6, TXD_3/P1.7
'P_sw1 = &HC0                              'Rxd_4/P4.3, Txd_4/P4.4

P_sw2 = &H00                              'RXD2/P1.0, TXD2/P1.1
'P_sw2 = &H01                              'RXD2_2/P4.6, TXD2_2/P4.7


' Выбираем оба UART
Auxr = &H15                               '0001_0101  UART 1 + 2
'Auxr = &H14                               '0001_0100  UART1


' Настройка UART1
Auxr = Auxr Or &H40                       'Timer clock is 1T mode
Auxr = Auxr And &HFE                      'UART 1 use Timer1 as baudrate generator
Tmod = Tmod And &H0F                      'Set timer work mode
Tl1 = &HE0 : Th1 = &HFE                   'Initial timer value 9600
Et1 = 0                                   'Disable Timer interrupt
Tr1 = 1                                   'Timer1 start run


' Настройка UART2
S2con = &H10                              ' 0010000
T2l = &HE8 : T2h = &HFF                   ' Initial timer value 115200


 Scon = &H50                               '8 Bits And Variable Baudrate

 Sbuf = 0                                 ' 1  Зачем - не знаю.
 S2buf = 0                                ' 2  Но без этого не работает


Open "COM2:" For Binary As #1             'open the port

Do
  Waitms 150

  Print "1 9600 Hello! " ; Temp ; Chr(temp)
  Print #1 , "2 115200 Hello! " ; Temp ; Chr(temp)

  Print "1 " ; Mstr$
  Print #1 , "2 " ; Mstr$


  If My_led = 1 Then                      ' Мигаем
    My_led = 0
  Else
    My_led = 1
  End If

  Incr Temp
Loop
Close #1


Отредактировано Александр Д. (2024-05-02 20:47:50)

0

3

I2C работает. ПРОГРАММНЫЙ, на любых выводах МК!  Аппаратный модуль пока не трогал
НО НАДО ПОНИМАТЬ КАК работает 8051 и КАК STC!
1. Настроить нужные выводы порта как Quasi (как в 8051) - иначе не читает.
2. Большие проблемы с тактовой! В описании к I2C указано, что рассчитана под МК с "одна команда за 12 тактов". У нас "1 команда = 1 такт". Скорость шины - бешеная!

Я опустил частоту МК до 2 МГц и только тогда завёл EEPROM 24LC64 на 100КГц

Код:
$regfile = "STC_8H.DAT"       ' STC registers list
$crystal = 2000000            ' CPU clock frequence
$ramsize = &H400              ' 1024
$romstart = &H0               ' code starting address

Dim Seco As Byte , Mine As Byte , Hour As Byte , Weekday As Byte
Dim Dat As Byte , Month As Byte , Year As Byte
Dim Temp As Byte , Temp_w As Byte , Adres_w As Word , Flag_sost As Byte
Dim L_adr_eeprom As Byte , H_adr_eeprom As Byte
Dim L_data As Byte , H_data As Byte


P1ie = &B1111_1111            ' 1: Enable digital pins
P1pu = &B0000_0000            ' 1: pull-up resistor
P1m1 = &B_0000_0000 : P1m0 = &B_1010_0010       ' 1=Push-pull   0=Quasu  output mode

P3ie = &B1111_1111            ' 1: Enable digital pins
P3pu = &B0000_0000            ' 1: pull-up resistor
P3m1 = &B0000_0000 : P3m0 = &B_1000_0010       ' 1=Push-pull output mode


My_led Alias P1.2

Config Sda = P1.3
Config Scl = P1.4
Config I2cdelay = 0           ' 100 KHz clock


' ---  DS1307  ---
Const Ds1307w = &HD0          ' адрес записи
Const Ds1307r = &HD1          ' адрес чтения

' ---  EEPROM 24C64  ---
Const Cmd_eeprom_w = &B10100000       '160 &hA0  адрес записи
Const Cmd_eeprom_r = &B10100001       '161 &hA1  адрес чтения


' Установим выводы для UART
P_sw1 = &H00                  'RXD/P3.0, TXD/P3.1
'P_sw1 = &H40                              'RXD_2/P3.6, TXD_2/P3.7
'P_sw1 = &H80                              'RXD_3/P1.6, TXD_3/P1.7

' Настройка UART1
Scon = &H50                   ' 8-Bits And Variable Baudrate
Sbuf = 0                      ' Зачем - не знаю. Но без этого не работает
Auxr = &H54                   'Timer is 1T mode, use Timer1 as baudrate generator
Tmod = Tmod And &H0F          'Set timer work mode
'Tl1 = &HE0 : Th1 = &HFE                   'Initial timer - 9600 на 11059200
'Tl1 = &HE8 : Th1 = &HFF                   'Initial timer - 115200 на 11059200
'Tl1 = &HF3 : Th1 = &HFF                   'Initial timer - 19200 на 1MHz
Tl1 = &HF3 : Th1 = &HFF       'Initial timer - 38400 на 2MHz


Et1 = 0                       'Disable Timer interrupt
Tr1 = 1                       'Timer1 start run


Print " START..."            ' start

Adres_w = 0
'For Adres_w = 0 To 31 'Step 32
  H_adr_eeprom = High(adres_w)
  L_adr_eeprom = Low(adres_w)       'adress of EEPROM

  I2cstart            ' читаем всю EEPROM
  I2cwbyte Cmd_eeprom_w
  I2cwbyte H_adr_eeprom       ' Пишем адрес, куда писать
  I2cwbyte L_adr_eeprom

  For Temp = 0 To 31
    I2cwbyte Temp
  Next
  I2cstop
  Waitms 15
  My_led = Not My_led
'Next


Waitms 250

For Adres_w = 0 To 31        ' читаем EEPROM
  My_led = Not My_led

  H_adr_eeprom = High(adres_w)
  L_adr_eeprom = Low(adres_w) 'adress of EEPROM

  I2cstart
  I2cwbyte Cmd_eeprom_w       '160 &hA0 адрес записи
  I2cwbyte H_adr_eeprom       ' Пишем адрес, откуда читать
  I2cwbyte L_adr_eeprom

  I2cstart                    ' repeated start
  I2cwbyte Cmd_eeprom_r       '161 &hA1

  I2crbyte Seco , Nack
  I2cstop

  Printbin Seco
Next

Print "OK"                 ' stop

Do
  Waitms 150
  My_led = Not My_led
Loop

ps
Запустил МК на 8 МГц и шина 400 Кгц - работает

Код:
$regfile = "STC_8H.DAT"       ' STC registers list
$crystal = 8000000            ' CPU clock frequence
$ramsize = &H400              ' 1024
$romstart = &H0               ' code starting address

Dim Seco As Byte , Mine As Byte , Hour As Byte , Weekday As Byte
Dim Dat As Byte , Month As Byte , Year As Byte
Dim Temp As Byte , Temp_w As Byte , Adres_w As Word , Flag_sost As Byte
Dim L_adr_eeprom As Byte , H_adr_eeprom As Byte
Dim L_data As Byte , H_data As Byte


P1ie = &B1111_1111            ' 1: Enable digital pins
P1pu = &B0000_0000            ' 1: pull-up resistor
P1m1 = &B_0000_0000 : P1m0 = &B_1010_0010       ' 1=Push-pull output mode

P3ie = &B1111_1111            ' 1: Enable digital pins
P3pu = &B0000_0000            ' 1: pull-up resistor
P3m1 = &B0000_0000 : P3m0 = &B_1000_0010       ' Push-pull output mode


My_led Alias P1.2

Config Sda = P1.3
Config Scl = P1.4
Config I2cdelay = 0           ' 400 KHz clock


' ---  DS1307  ---
Const Ds1307w = &HD0          ' адрес записи
Const Ds1307r = &HD1          ' адрес чтения

' ---  EEPROM 24C64  ---
Const Cmd_eeprom_w = &B10100000       '160 &hA0  адрес записи
Const Cmd_eeprom_r = &B10100001       '161 &hA1  адрес чтения


' Установим выводы для UART
P_sw1 = &H00                  'RXD/P3.0, TXD/P3.1
'P_sw1 = &H40                              'RXD_2/P3.6, TXD_2/P3.7
'P_sw1 = &H80                              'RXD_3/P1.6, TXD_3/P1.7

' Настройка UART1
Scon = &H50                   ' 8-Bits And Variable Baudrate
Sbuf = 0                      ' Зачем - не знаю. Но без этого не работает
Auxr = &H54                   'Timer is 1T mode, use Timer1 as baudrate generator
Tmod = Tmod And &H0F          'Set timer work mode
'Tl1 = &HE0 : Th1 = &HFE                   'Initial timer - 9600 на 11059200
'Tl1 = &HE8 : Th1 = &HFF                   'Initial timer - 115200 на 11059200
'Tl1 = &HF3 : Th1 = &HFF                   'Initial timer - 19200 на 1MHz
'Tl1 = &HF3 : Th1 = &HFF                   'Initial timer - 38400 на 2MHz
Tl1 = &HCC : Th1 = &HFF       'Initial timer - 38400 на 8MHz


Et1 = 0                       'Disable Timer interrupt
Tr1 = 1                       'Timer1 start run


Print " START..."             ' start

For Adres_w = 0 To 31         'Step 32
  H_adr_eeprom = High(adres_w)
  L_adr_eeprom = Low(adres_w) 'adress of EEPROM

  I2cstart                    ' читаем всю EEPROM
  I2cwbyte Cmd_eeprom_w
  I2cwbyte H_adr_eeprom       ' Пишем адрес, куда писать
  I2cwbyte L_adr_eeprom

  For Temp = 0 To 31
    Weekday = Temp + 32
    I2cwbyte Weekday
  Next
  I2cstop
  Waitms 15
  My_led = Not My_led
Next


Waitms 250

For Adres_w = 0 To 31         ' читаем EEPROM
  My_led = Not My_led

  H_adr_eeprom = High(adres_w)
  L_adr_eeprom = Low(adres_w) 'adress of EEPROM

  I2cstart
  I2cwbyte Cmd_eeprom_w       '160 &hA0 адрес записи
  I2cwbyte H_adr_eeprom       ' Пишем адрес, откуда читать
  I2cwbyte L_adr_eeprom

  I2cstart                    ' repeated start
  I2cwbyte Cmd_eeprom_r       '161 &hA1

  I2crbyte Seco , Nack
  I2cstop

  Printbin Seco
Next
'I2crbyte Seco , Nack

Print "^OK^"                  ' stop

Do
  Waitms 150
  My_led = Not My_led
Loop,

0

4

Работает софтовый PRINT
Т.е., на любом выводе
НО скорость связи в 8 раз выше заданной вами.
Следовательно, если вам надо 9600 ставьте 1200

Код:
$regfile = "STC_8H.DAT"                   ' STC registers list
$crystal = 8000000                        ' CPU clock frequence '11059200
$romstart = &H0                           ' code starting address

Dim Temp As Byte , Temp_w As Byte , Adres_w As Word , Flag_sost As Byte
Dim S$ As String * 16 , I As Byte , A As Byte

P1ie = &B1111_1111                        ' 1: Enable digital pins
P1pu = &B0000_0000                        ' 1: pull-up resistor
P1m0 = &B0000_0000 : P1m1 = &B0000_0000   ' 1=Push-pull output mode

P3ie = &B1111_1111                        ' 1: Enable digital pins
P3pu = &B0000_0000                        ' 1: pull-up resistor
P3m0 = &B1111_1111 : P3m1 = &B0000_0000   ' 1=Push-pull output mode


My_led Alias P1.2

S$ = "Test this! " + Chr(10) + Chr(13)    'assign string
Temp = Len(s$)                            'get length of string

'Open "com1.1:1200" For Output As #1         ' 9600
Open "com1.1:4800" For Output As #1       ' 38400

Do
 For I = 1 To Temp                        'for all characters from left to right
  A = Mid(s$ , I , 1)                     'get character
  Put #1 , A                              'write it to comport
 Next

 Waitms 255
 My_led = Not My_led
Loop                                      ' finally close device

Close #1

0

5

решение тупо в лоб:
умножить тактовую на 8 и так указать в $crystal
то есть, ваш МК работает на 8 Мгц, значит пишем: $crystal = 64000000

Заодно решилась проблема с командами задержек Waitms и Wait: до этого тоже были ускорены на 8!
Немного диковато, но работает ))

Код:
$regfile = "STC_8H.DAT"                   ' STC registers list
$crystal = 64000000                       ' CPU clock frequence '11059200
$romstart = &H0                           ' code starting address

Dim Temp As Byte , Temp_w As Byte , Adres_w As Word , Flag_sost As Byte

P1ie = &B1111_1111                        ' 1: Enable digital pins
P1pu = &B0000_0000                        ' 1: pull-up resistor
P1m0 = &B1111_1111 : P1m1 = &B0000_0000   ' 1=Push-pull output mode

P3ie = &B1111_1111                        ' 1: Enable digital pins
P3pu = &B0000_0000                        ' 1: pull-up resistor
P3m0 = &B1111_1111 : P3m1 = &B0000_0000   ' 1=Push-pull output mode


My_led Alias P1.2



Dim S$ As String * 16 , I As Byte , A As Byte

S$ = "Test this! " + Chr(10) + Chr(13)    'assign string
Temp = Len(s$)                            'get length of string

Open "com1.1:9600" For Output As #1

Do
 For I = 1 To Temp                        'for all characters from left to right
  A = Mid(s$ , I , 1)                     'get character
  Put #1 , A                              'write it to comport
 Next

 Waitms 100
 My_led = Not My_led
Loop                                      ' finally close device

Close #1

0

6

Может, в DAT что-то не так указано, что заставляет компилятор "включать" делитель /8 ?

0

7

или я не так трактовал параметр clockdiv?
Интересную идею подкинули )) Сейчас узнаю...

ps
не, clockdiv=1 - максимальное значение
Фактически, надо параметр Умножение тактовой , а не её Деление :)

PPS
Кстати: если НЕ указать этот параметр в DAT-файле, то BASCOM-8051 по умолчанию принимает значение равным 12.

Отредактировано Александр Д. (2024-05-12 13:36:16)

0

8

Хотя, наверное, возьму слова обратно: банальное умножение тактовой как-то не очень подтвердилось. Т.е, сработало для данной скорости и данного значения тактовой.
Выставил кварц на 11.0592 МГц и скорость связи 4800 - принимаю на 9600

ps
Вообще не понимаю, но факт :)

МК настроен на 8МГц,
В программе Баском устанавливаю 11059200/2= 5529600
Все скорости программного UART - работают! Проверил связь от 1200 до 115200

Так что если кому это важно: ставим как я выше указал и спокойно работаем...

0

9

Александр Д. написал(а):

Интересную идею подкинули ))

Когда я боролся с DAT-файлом под ATTiny 10, то так и не нашел, где там прописывается тактовая частота "по умолчанию"...
В итоге при загрузки профиля МК в Редактор выставляется т.ч. из "донорского" DAT-файла ATTiny 13, приходится вручную править... ;)

Но ведь где-то этот "суслик" живет же... ;)

0

10

Факт таков:
МК настроен на 8МГц,
В программе Баском устанавливаю 11059200/2= 5529600
Все скорости программного UART - работают! Проверил от 1200 до 115200

Паузы:
Пишу, mS   Фактически
10            10,4
20            20,8
30            31,2
40            41,6
50            52
100          104
200          208
250          260           

1sec         1,04
2sec         2,08

0

11

Александр Д. написал(а):

"big problem with clock"

if i understand correctly what i read, clockdiv=12
you can crosscheck it with 90C2051.dat which is atmel's 8051 which also runns in 1/clock /per instruction mode

Отредактировано plouf (2024-05-09 01:16:18)

0

12

не деление, а умножение получается.
Я пробовал выставить разные значения в файле описания чипа, но только =1 является оптимальным решением.

Not division, but multiplication is obtained.
I tried setting different values ​​in the chip description file, but only =1 is the optimal solution.

0