ATMega48 рдкрд░ рдПрдХ рдШрдбрд╝реА рдХреЗ рд╕рд╛рде рд╡рд┐рдлрд▓рддрд╛

рдПрдХ рдПрд▓рд╕реАрдбреА рдбрд┐рд╕реНрдкреНрд▓реЗ рдФрд░ ATMega48 supermicrocircirc рдкрд░ рд╢рд╛рдирджрд╛рд░ рдШрдбрд╝рд┐рдпрд╛рдБред рд▓реЗрдХрд┐рди рдЙрдиреНрд╣реЛрдВрдиреЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд┐рдпрд╛ред



UPD : рдХреНрд░реЛрд╣рди рдХреА рдореГрддреНрдпреБ рд╣реЛ рдЧрдИ, рджреЛ рддрд╛рд░реЛрдВ рдХреЛ рдХрд╛рдЯ рджрд┐рдпрд╛, рдиреАрдВрдж рд▓рд╛рдЧреВ рдХреА, 0.3-1.6mA


рдпрд╣реА рд╣реИ, рдШрдбрд╝рд┐рдпреЛрдВ, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди, рдЕрдлрд╕реЛрд╕, рд╡реЗ рд▓рдВрдмреЗ рд╕рдордп рддрдХ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред


рдПрдХ рдмрд╛рд░, рджреВрд░ рд░рд╛рддреНрд░рд┐рд╕реНрддрдВрдн рдореЗрдВ рдПрдХ рдмреЙрдХреНрд╕ рдореЗрдВ рдореИрдВрдиреЗ рд╕рд╛рдд-рдЦрдВрдб рд╡рд╛рд▓реЗ рдПрд▓рд╕реАрдбреА рд╕рдВрдХреЗрддрдХреЛрдВ рдХреЗ рдПрдХ рдЬреЛрдбрд╝реЗ рдХреЛ рд▓рдЯрдХрд╛ рджрд┐рдпрд╛ред рдФрд░ рдЕрднреА рдХреБрдЫ рд╕рдордп рдкрд╣рд▓реЗ, рдореИрдВ рдЙрдиреНрд╣реЗрдВ рд╕рдВрдЪрд▓рди рдореЗрдВ рд▓реЗ рдЬрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рдФрд░ рдЙрдирдореЗрдВ рд╕реЗ рдПрдХ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдПрдХ рдШрдбрд╝реА рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ред рдПрдХ рдмрд╛рд░ рдПрдХ рдмрд╛рд░: рдпрд╣ рд╕рдЪрдореБрдЪ, рд╕рд╛рдд рд╕рд╛рд▓ рд╣реИред рдпрд╣ 2011 рдореЗрдВ рдерд╛, рддрдм рдореБрдЭреЗ рдЗрд▓реЗрдХреНрдЯреНрд░реЙрдирд┐рдХреНрд╕ рдореЗрдВ рджрд┐рд▓рдЪрд╕реНрдкреА рд╣реБрдИред рд▓рдВрдмреЗ рд╕рдордп рддрдХ рд╕реЛрдЪрдиреЗ рдХреЗ рдмрд┐рдирд╛, рдореИрдВрдиреЗ рдлрд┐рд░ рдПрдХ рдЕрдЪреНрдЫреЗ рдСрдирд▓рд╛рдЗрди рд╕реНрдЯреЛрд░ рдореЗрдВ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреА рдЪреАрдЬреЛрдВ рдХрд╛ рдЖрджреЗрд╢ рджрд┐рдпрд╛ (рдирд╣реАрдВ, рдЕрд▓реА рдкрд░ рдирд╣реАрдВ; рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╡рд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╡рд╣рд╛рдВ рдерд╛)ред рд▓реЗрдХрд┐рди рдЕрдирдиреНрдд рдХреЛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рддрд░рд╣ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд┐рдпрд╛ред рдХрдИ etched рдмреЛрд░реНрдбреЛрдВ рдХреЗ рдмрд╛рдж, рдореИрдВрдиреЗ рдЗрд╕ рдордиреЛрд░рдВрдЬрди рдХреЛ рддреНрдпрд╛рдЧ рджрд┐рдпрд╛ рдФрд░ рднреВрд▓ рдЧрдпрд╛ред


рдФрд░ рдЗрд╕рд▓рд┐рдП, рдЬрдм рдЕрд▓реА рдХреЛ рдореЙрдХ-рдЕрдк рд╡рд╛рд▓реЗ рдкреИрдХреЗрдЬ рдорд┐рд▓реЗ, рдбреБрдмрдХреА рд╡рд╛рд▓реЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ 595 рдХрд╛ рдкреИрдХреЗрдЯ, ds1307 рдкрд░ рдЯрд┐рдиреА рдЖрд░рдЯреАрд╕реА, рдФрд░ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд, USBasp , рдпрд╣ рдкреБрд░рд╛рдиреЗ рд╡рд┐рдЪрд╛рд░ рдкрд░ рд▓реМрдЯрдиреЗ рдХрд╛ рд╕рдордп рдерд╛ред рдкреБрд░рд╛рдиреЗ рд╕реНрдЯреИрд╢ рд╕реЗ рдореЗрд░реЗ рдкрд╛рд╕ ATMega48 рдерд╛ , рдЬрд┐рд╕рдореЗрдВ рд╕реЗ 28 рдкреИрд░, lm7805 , рдкреНрд░рддрд┐рд░реЛрдзрдХ / рдХреИрдкреЗрд╕рд┐рдЯрд░ / рдмрдЯрди рдХреЗ рд░реВрдк рдореЗрдВ рд╕рднреА рдЫреЛрдЯреА рдЪреАрдЬреЗрдВ, рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, 40 рдкреИрд░реЛрдВ рдкрд░ рдПрдХ рд╕рдВрдХреЗрддрдХред


рд╕рд╛рдорд╛рдиреНрдпрддрдпрд╛, рдпрд╣ рдореВрд▓ рд░реВрдк рд╕реЗ AtTiny13 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛рдИ рдЧрдИ рдереА, рдЬрд┐рд╕реЗ рдореИрдВ рднреА рд░реЛрд▓ рдХрд░рддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░, рдореБрдЭреЗ рдпрд╣ рдкрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╕рдВрдХреЗрддрдХ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рдЧрднрдЧ 5 рдкреИрд░реЛрдВ рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ, рджреЛ рдмрдЯрди рдкрдврд╝реЗрдВ, рдФрд░ iCc рдШрдбрд╝реА рдХреЗ рд╕рд╛рде рд╕рдВрд╡рд╛рдж рдХрд░реЗрдВред 28 рдореЗрдЧрд╛ рдкреИрд░реЛрдВ рдХреЗ рд╕рд╛рде, рдкреИрд░реЛрдВ рдХреЗ рдорд┐рд▓рди рдХреЗ рд╕рд╛рде рдмрдЪрдд рдФрд░ рдЪрдХреНрдХрд░ рд▓рдЧрд╛рдирд╛ рдЕрдм рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЖрдк 595 рдХреЗ рдмрд┐рдирд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдореИрдВрдиреЗ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдореЗрдВ рдПрдХ рдХрд┐рд╢реЛрд░реА рд╕реЗ рд╕рдВрдХреЗрддрдХ рдХреЗ рд▓рд┐рдП рд╕рднреА 32 рдмрд┐рдЯреНрд╕ рдХреЗ рдбреЗрдЯрд╛ рдХреЛ рдЖрдЙрдЯрдкреБрдЯ рдХрд░рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛рдИ рд╣реИ, рддреЛ рдореЗрдЧрд╛ рдХреЗ рд╕рд╛рде рдЖрдк рдПрдХ рдмрд╛рд░ рдореЗрдВ рд╕рднреА рдЪрд╛рд░ рдорд╛рдЗрдХреНрд░реЛ рд╕рд░реНрдХрд┐рдЯ рдкрд░ рдПрдХ рдЪрд┐рддреНрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред



рд╕рднреА 595 рд╕рдВрдХреЗрддрдХ рдХреЗ рдиреАрдЪреЗ рдЫрд┐рдкреЗ рд╣реБрдП рд╣реИрдВред рддрд╕реНрд╡реАрд░ рдЪрд┐рдк рдХреЗ рдЖрд╡рд╛рд╕ рдХреЗ рдирд┐рд╖реНрдХрд░реНрд╖ рдХреЛ рджрд┐рдЦрд╛рддреА рд╣реИред


595 рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЪрд╛рд░ рдЯреБрдХрдбрд╝реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ рд╕рдВрдХреЗрддрдХ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЗрд╕рдореЗрдВ 40 рдкреИрд░ рд╣реИрдВ, рдЬреЛ рдХреЗрд╡рд▓ 32 рдЦрдВрдбреЛрдВ рдкрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛрддрд╛ рд╣реИред рдХрд╛рд╢, рдпрд╣ рдХреЗрд╡рд▓ 3.5 рд╕рдВрдХреЗрддрдХ рд╣реИ, рдЕрд░реНрдерд╛рдд рдЗрд╕рдореЗрдВ 3 рдкреВрд░реНрдг рдЕрдВрдХ рд╣реИрдВ, рдкреНрд▓рд╕ рдПрдХред рд╕реЗрдХрдВрдб рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░рддреАрдХ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдПрдо / рдкреАрдПрдо рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдкрджрдирд╛рдо рдирд╣реАрдВ рд╣реИред рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╣реИред рдореИрдВ рдЕрдкрдиреЗ рдЬреАрд╡рди рдореЗрдВ рдПрд▓рд╕реАрдбреА рд╕рдВрдХреЗрддрдХреЛрдВ рдореЗрдВ рдХреБрдЫ рднреА рдПрдХрддреНрд░ рдХрд┐рдП рдмрд┐рдирд╛ рдЕрдзрд┐рдХ рдЙрдиреНрдирдд рд╕рдВрдХреЗрддрдХ рдХрд╛ рдЖрджреЗрд╢ рдирд╣реАрдВ рджреЗрдирд╛ рдЪрд╛рд╣рддрд╛ред



рд╕рдВрдХреЗрддрдХ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдп рдкреНрд░рд▓реЗрдЦрдиред рдкрд░реАрдХреНрд╖рдХ рдХреЛ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдирд╛ рдерд╛ рдХрд┐ рдХреМрди рд╕рд╛ рдкреИрд░ рдХрд┐рд╕ рдЦрдВрдб рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИред


рдЦреИрд░, рдлрд┐рд░ рддрдХрдиреАрдХ рдХреА рдмрд╛рддред рдХрднреА рдХреЛрдИ рдпреЛрдЬрдирд╛ рдирд╣реАрдВ рдереА, рд▓реЗрдХрд┐рди рд╡рд╣рд╛рдВ рд╕рдм рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рд╣реИред рдХреЗрд╡рд▓ рдмрдлрд╝рд░реНрд╕ рдХреЗ рдЗрдирдкреБрдЯ рдХреЗ рд▓рд┐рдП рдЪрд╛рд░ рдкреИрд░реЛрдВ рдХрд╛ рдЪрдпрди рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛, рд╕реВрдЪрдХ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдкреИрд░, SCLK / RCLK рдХреЗ рд▓рд┐рдП рдПрдХ рдкреИрд░, OE рдХреЗ рд▓рд┐рдП рдПрдХ рдкреИрд░, i2c рдХреЗ рд▓рд┐рдП рджреЛ рдкреИрд░, рдмрдЯрдиреЛрдВ рдХреЗ рд▓рд┐рдП рджреЛ рдкреИрд░ред рдпрд╣ рд╕рдм, рдЬрд╝рд╛рд╣рд┐рд░ рд╣реИ, рдЧрд▓рдд рдерд╛ред рдореИрдВрдиреЗ рдпрд╣ рдХреНрдпреЛрдВ рддрдп рдХрд┐рдпрд╛ рдХрд┐ OE рдХреЛ рдирд┐рдпрдВрддреНрд░рдХ рдкрд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ SCLK рдХреЛ RCLK рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ - рдореБрдЭреЗ рдпрд╣ рд╕реНрд╡рдпрдВ рдпрд╛рдж рдирд╣реАрдВ рд╣реИред рдмрд╕ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛ред рдФрд░ рдирд┐рдпрдВрддреНрд░рдХ рдкрд░ рд╕рд╛рдорд╛рдиреНрдп рд╕рдВрдХреЗрддрдХ рддрд╛рд░ рдХреА рдмрд┐рд▓реНрдХреБрд▓ рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдкрд╣рд▓реЗ 595 рд╡реЗрдВ рдирд┐рд╖реНрдХрд░реНрд╖ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЛ (рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдореИрдВрдиреЗ рднреА рдХрд┐рдпрд╛ рдерд╛, рдЕрдВрдд рдореЗрдВ) рддрд┐рд░рд╕реНрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред



рддрд╛рд░реЛрдВред рдЙрдирдореЗрдВ рд╕реЗ рдмрд╣реБрдд рд╕рд╛рд░реЗред рдЕрдВрджрд░ рдХрд╛ рдирдЬрд╝рд╛рд░рд╛ред



рдмрд╛рд╣рд░ рд╕реЗ рджреГрд╢реНрдпред


рдЗрд╕ рд╕рднреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рдмрд╛рдд: рд╕рдВрдХреЗрддрдХ рдХреЗ рд▓рд┐рдП рдЖрдЙрдЯрдкреБрдЯ рдХреЛрдбред рд╕реВрдХреНрд╖реНрдорддрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЖрдк рдХреЗрд╡рд▓ LCD рд╕рдВрдХреЗрддрдХ рдкрд░ рд╡реЛрд▓реНрдЯреЗрдЬ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рднреВрд▓ рд╕рдХрддреЗ рд╣реИрдВред рдЦрдВрдбреЛрдВ рдФрд░ рдЖрдо рд╕рдВрдкрд░реНрдХ рдХреЗ рдмреАрдЪ рдзреНрд░реБрд╡реАрдпрддрд╛ рдХреЛ рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб рд╕реМ рдмрд╛рд░ рдмрджрд▓рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рддрд╛рдХрд┐ рд╕рдм рдХреБрдЫ рд╕реБрдВрджрд░ рд╣реЛ рдФрд░ рдЖрдВрдЦ рдХреЛ рдкреНрд░рд╕рдиреНрди рд╣реЛред рдПрдХ рд╡рд┐рдХрд╛рд╕ рдХреЗ рдорд╛рд╣реМрд▓ рдХреЗ рд░реВрдк рдореЗрдВ, рдЖрдЧреЗ рдХреА рд╣рд▓рдЪрд▓ рдХреЗ рдмрд┐рдирд╛, рдореИрдВрдиреЗ Arduino IDE рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛, рдХреЗрд╡рд▓ рдХреБрдЫ рдмрд┐рдВрджреБрдУрдВ рдореЗрдВ рдереЛрдбрд╝реА рдкреАрдбрд╝рд╛ред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдореБрдЭреЗ MiniCore рдкреИрдХреЗрдЬ ( https://github.com/MCUdude/MiniCore ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ рдореБрдЭреЗ рдПрдХ рдмрдбрд╝реЗ рд░реЗрдбреА-рдореЗрдб arduino рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдПрдХ рдХрдордЬреЛрд░ рдФрд░ рдирдВрдЧреЗ ATMega48 рдХреЗ рд▓рд┐рдП рд▓рд┐рдЦрдирд╛ рдерд╛ред рджреВрд╕рд░реЗ, i2c рдХреЗ рд▓рд┐рдП рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рд╕реАрдзрд╛ рдкреНрд░рдпрд╛рд╕ рд╡рд┐рдлрд▓ рд░рд╣рд╛ред рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ, рдпрд╣ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛, рдореБрдЭреЗ рдПрдХ рдФрд░ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдЦреЛрдЬрдирд╛ рдерд╛, рдФрд░ рдлрд┐рд░ рдЗрд╕реЗ рдЕрдкрдиреА рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЯреНрд░рд┐рдо рдХрд░рдирд╛ рдерд╛ред


рдЬреИрд╕рд╛ рдХрд┐ рдпрд╣ рдирд┐рдХрд▓рд╛, 4 рдХрд┐рд▓реЛрдмрд╛рдЗрдЯ рдмрд╣реБрдд рдЫреЛрдЯрд╛ рд╣реИред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдпрджрд┐ рдЖрдк рд╕реА рдореЗрдВ рд▓рд┐рдЦрддреЗ рд╣реИрдВред рд╢рд╛рдпрдж рдЕрдЧрд░ рдореИрдВрдиреЗ рдЕрд╕реЗрдВрдмрд▓рд░ рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рдпрд╣ рдкреНрд░рддрд┐рдмрдВрдз рдЗрддрдиреА рдЧрдВрднреАрд░рддрд╛ рд╕реЗ рдирд╣реАрдВ рджрдмрд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдПрд╡реАрдЖрд░ рдХреЗ рд▓рд┐рдП рдХреЛрдбрд╛рдВрддрд░рдХ рдореЗрдВ рд▓рд┐рдЦрд┐рдд рд░реВрдк рдореЗрдВ рдореЗрд░реЗ рдкрд┐рдЫрд▓реЗ рдЕрдВрд╢реЛрдВ рдХреЛ рдпрд╛рдж рдХрд░рддреЗ рд╣реБрдП, рдореБрдЭреЗ рдРрд╕реА рдЗрдЪреНрдЫрд╛ рдирд╣реАрдВ рдереАред рдФрд░ рд╕реА рдореЗрдВ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП - рдмрд╣реБрдд рд╕реА рдЬрдЧрд╣ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдореИрдВрдиреЗ рдЕрдирдЬрд╛рдиреЗ рдореЗрдВ рдереЛрдбрд╝рд╛ рдмреНрд░реИрдХреЗрдЯ рдбрд╛рд▓ рджрд┐рдпрд╛ - рдкрд╛рдЗрдк рдореЗрдВ рдПрдХ рд╕реМ рдмрд╛рдЗрдЯреНрд╕ред


рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреЛрдб рдЯрд┐рдкреНрдкрдгреА рдХреА
#include <avr/io.h>
#include <util/delay.h>
#include <avr/power.h>

#define cbi(sfr, bit)   (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit)   (_SFR_BYTE(sfr) |= _BV(bit))

//      ds1307,    
#define DS3231_I2C_ADDRESS 0x68

#define LCD_PORT PORTD
#define LCD_DDR DDRD
#define LCD_DATA1 PD0
#define LCD_DATA2 PD1
#define LCD_DATA3 PD2
#define LCD_DATA4 PD3
#define LCD_SCLK PD4
#define LCD_OE PD5
#define LCD_COM PD6

#define KEY1_PORT PORTB
#define KEY1_DDR DDRB
#define KEY1_PIN PINB
#define KEY1 PB0
#define KEY2_PORT PORTD
#define KEY2_DDR DDRD
#define KEY2_PIN PIND
#define KEY2 PD7

#define DS1307SQ PB1
#define DS1307SQ_INT PCIE0
#define DS1307SQ_PORT PORTB
#define DS1307SQ_DDR DDRB
#define DS1307SQ_PIN PINB
#define DS1307SQ_VEC PCINT0_vect
#define DS1307SQ_MSK PCMSK0

//  . , -, , -     
#define LM335_PORT PORTC
#define LM335_DDR DDRC
#define LM335 PC3

//  
unsigned char lcd_buf[4];

#define MODE_MAIN 0
#define MODE_CALENDAR 1
#define MODE_YEAR 2
#define MODE_TERMOMETER 3 // 
#define MODE_VOLTMETER 4 // 
#define MODE_SET_MINUTE 5
#define MODE_SET_HOUR 6
#define MODE_SET_DAY 7
#define MODE_SET_MONTH 8
#define MODE_SET_YEAR 9
#define MODE_SECOND 10
#define MODE_DEBUG 11 //  

//        10ms ()
#define MODE_TIMEOUT 20 // 2 
#define MODE_TIMEOUT_SET 100 // 10 
#define KEY_TIMEOUT 10 // 1 

byte mode = MODE_MAIN;
byte mode_timeout = 0;

byte key1_press = 0;
byte key1_time = 0;
byte key2_press = 0;
byte key2_time = 0;

byte cycle_count_10 = 0; //   
byte even_10 = 0; //    1/10 

//    ds1307
byte second;
byte minute;
byte hour;
byte dayOfWeek;
byte dayOfMonth;
byte month;
byte year;

volatile byte need_render_int = 1;
uint8_t porthistory = 0xFF;
volatile uint8_t debug_value = 0;

byte twi_problems = 0;

//    ds1307   SQ
//   ,     
ISR(DS1307SQ_VEC) {
  uint8_t changedbits = DS1307SQ_PIN ^ porthistory;
  porthistory = DS1307SQ_PIN;
  if (changedbits & _BV(DS1307SQ) && porthistory & _BV(DS1307SQ)) {
    need_render_int = 1;
  }
}

//       
void lcd_num(char pos, char num) {
  unsigned char buf = 0b01110110;
  if (pos < 1 || pos > 3) {
    return;
  }
  switch (num) {
    case 0:
      //      3-   ,   ?
      // ,     ,     
      //   :-(
      if (pos == 3) {
        buf = 0b11101110;
      } else {
        buf = 0b11100111;
      }
      break;
    case 1:
      if (pos == 3) {
        buf = 0b10001000;
      } else {
        buf = 0b10000001;
      }
      break;
    case 2:
      buf = 0b11010110;
      break;
    case 3:
      if (pos == 3) {
        buf = 0b11011100;
      } else {
        buf = 0b11010011;
      }
      break;
    case 4:
      if (pos == 3) {
        buf = 0b10111000;
      } else {
        buf = 0b10110001;
      }
      break;
    case 5:
      if (pos == 3) {
        buf = 0b01111100;
      } else {
        buf = 0b01110011;
      }
      break;
    case 6:
      if (pos == 3) {
        buf = 0b01111110;
      } else {
        buf = 0b01110111;
      }
      break;
    case 7:
      if (pos == 3) {
        buf = 0b11001000;
      } else {
        buf = 0b11000001;
      }
      break;
    case 8:
      if (pos == 3) {
        buf = 0b11111110;
      } else {
        buf = 0b11110111;
      }
      break;
    case 9:
      if (pos == 3) {
        buf = 0b11111100;
      } else {
        buf = 0b11110011;
      }
      break;
  }
  lcd_buf[pos] = buf;
}

//  
void lcd_one(bool e) {
  if (e) {
    lcd_buf[0] |= (1 << 0);
  } else {
    lcd_buf[0] &= ~(1 << 0);
  }
}
void lcd_sec(bool e) {
  if (e) {
    lcd_buf[0] |= (1 << 7);
  } else {
    lcd_buf[0] &= ~(1 << 7);
  }
}
void lcd_minus(bool e) {
  if (e) {
    lcd_buf[0] |= (1 << 1);
  } else {
    lcd_buf[0] &= ~(1 << 1);
  }
}
void lcd_plus(bool e) {
  if (e) {
    lcd_buf[0] |= (1 << 6);
  } else {
    lcd_buf[0] &= ~(1 << 6);
  }
}
void lcd_lo(bool e) {
  if (e) {
    lcd_buf[0] |= (1 << 5);
  } else {
    lcd_buf[0] &= ~(1 << 5);
  }
}
void lcd_over(bool e) {
  if (e) {
    lcd_buf[0] |= (1 << 4);
  } else {
    lcd_buf[0] &= ~(1 << 4);
  }
}
void lcd_dot(int pos, bool e) {
  int pos_buf;
  if (pos == 1) {
    pos_buf = 3;
  } else if (pos == 2) {
    pos_buf = 2;
  } else if (pos == 3) {
    pos_buf = 1;
  } else {
    return;
  }
  if (pos_buf == 3) {
    if (e) {
      lcd_buf[pos_buf] |= (1 << 0);
    } else {
      lcd_buf[pos_buf] &= ~(1 << 0);
    }
  } else {
    if (e) {
      lcd_buf[pos_buf] |= (1 << 3);
    } else {
      lcd_buf[pos_buf] &= ~(1 << 3);
    }
  }
}

//     100   
//    595-,    
void lcd_refresh() {
  unsigned char data1 = lcd_buf[0];
  unsigned char data2 = lcd_buf[1];
  unsigned char data3 = lcd_buf[2];
  unsigned char data4 = lcd_buf[3];
  byte reverse = data1 & (1 << 3); //      
  if (reverse) { //    ,  
    data1 = ~data1;
    data2 = ~data2;
    data3 = ~data3;
    data4 = ~data4;
  }
  for (int i = 0; i < 8; i++) {
    //          
    if (data1 & (1 << i)) {
      LCD_PORT |= _BV(LCD_DATA1);
    } else {
      LCD_PORT &= ~_BV(LCD_DATA1);
    }
    if (data2 & (1 << i)) {
      LCD_PORT |= _BV(LCD_DATA2);
    } else {
      LCD_PORT &= ~_BV(LCD_DATA2);
    }
    if (data3 & (1 << i)) {
      LCD_PORT |= _BV(LCD_DATA3);
    } else {
      LCD_PORT &= ~_BV(LCD_DATA3);
    }
    if (data4 & (1 << i)) {
      LCD_PORT |= _BV(LCD_DATA4);
    } else {
      LCD_PORT &= ~_BV(LCD_DATA4);
    }
    // SCLK 595- 
    sbi(LCD_PORT, LCD_SCLK);
    // SCLK 595- 
    cbi(LCD_PORT, LCD_SCLK);
  }
  //    SCLK
  //       SCLK   RCLK     ,    
  //     .
  //   , -, .       
  // SCLK  RCLK,  OE     (.   74HC595)
  //    .
  sbi(LCD_PORT, LCD_SCLK);
  cbi(LCD_PORT, LCD_SCLK);
  //    -   
  // -   -   ,  1  40
  // (-    ;     )
  //      4   595-,     
  //   ,    
  if (reverse) {
    sbi(LCD_PORT, LCD_COM);
  } else {
    cbi(LCD_PORT, LCD_COM);
  }
  //     
  lcd_buf[0] ^= (1 << 3);
}

//        ,     
void do_render() {
  lcd_buf[0] = 0;
  lcd_buf[1] = 0;
  lcd_buf[2] = 0;
  lcd_buf[3] = 0;
  if (twi_problems) {
    lcd_lo(1);
  }
  if (mode == MODE_MAIN) {
    lcd_num(3, minute % 10);
    lcd_num(2, minute / 10);
    byte hour1 = (hour <= 12) ? hour : (hour % 12);
    lcd_num(1, hour1 % 10);
    if (hour1 >= 10) {
      lcd_one(1);
    }
    //     ,   . .
    //         SQ  ,
    //     ,        
    //     
    if (second % 2) {
      lcd_sec(1);
    }
  } else if (mode == MODE_CALENDAR) {
    lcd_num(3, dayOfMonth % 10);
    lcd_num(2, dayOfMonth / 10);
    lcd_num(1, month % 10);
    if (month >= 10) {
      lcd_one(1);
    } else {
      lcd_one(0);
    }
    lcd_dot(2, 1);
  } else if (mode == MODE_YEAR) {
    lcd_num(3, year % 10);
    lcd_num(2, year / 10);
    lcd_buf[1] = 0b10110011; //   y. 
  } else if (mode == MODE_TERMOMETER) {
  } else if (mode == MODE_VOLTMETER) {
  } else if (mode == MODE_SET_MINUTE) {
    if (even_10) {
      lcd_num(3, minute % 10);
      lcd_num(2, minute / 10);
    }
    byte hour1 = (hour <= 12) ? hour : (hour % 12);
    lcd_num(1, hour1 % 10);
    if (hour1 >= 10) {
      lcd_one(1);
    } else {
      lcd_one(0);
    }
    lcd_sec(1);
  } else if (mode == MODE_SET_HOUR) {
    lcd_num(3, minute % 10);
    lcd_num(2, minute / 10);
    if (even_10) {
      byte hour1 = (hour <= 12) ? hour : (hour % 12);
      lcd_num(1, hour1 % 10);
      if (hour1 >= 10) {
        lcd_one(1);
      } else {
        lcd_one(0);
      }
      if (hour > 12) {
        lcd_over(1);
      } else {
        lcd_over(0);
      }
    }
    lcd_sec(1);
  } else if (mode == MODE_SET_DAY) {
    if (even_10) {
      lcd_num(3, dayOfMonth % 10);
      lcd_num(2, dayOfMonth / 10);
    }
    lcd_num(1, month % 10);
    if (month >= 10) {
      lcd_one(1);
    } else {
      lcd_one(0);
    }
    lcd_dot(2, 1);
  } else if (mode == MODE_SET_MONTH) {
    lcd_num(3, dayOfMonth % 10);
    lcd_num(2, dayOfMonth / 10);
    if (even_10) {
      lcd_num(1, month % 10);
      if (month >= 10) {
        lcd_one(1);
      } else {
        lcd_one(0);
      }
    }
    lcd_dot(2, 1);
  } else if (mode == MODE_SET_YEAR) {
    if (even_10) {
      lcd_num(3, year % 10);
      lcd_num(2, year / 10);
    }
    lcd_buf[1] = 0b10110011;
  } else if (mode == MODE_SECOND) {
    lcd_sec(1);
    lcd_num(3, second % 10);
    lcd_num(2, second / 10);
  } else if (mode == MODE_DEBUG) {
    byte d = debug_value;
    lcd_num(3, d % 10);
    d /= 10;
    lcd_num(2, d % 10);
    lcd_num(2, d / 10);
  }
}

int main(void)
{
  // -    .
  // , ,  .
  // ACSR = (1<<ACD);
  ADCSRA = (0<<ADEN);
  PRR = (1<<PRTIM0) | (1<<PRTIM1) | (1<<PRTIM2) | (1<<PRSPI) | (1<<PRADC) | (1<<PRUSART0);

  // 
  DDRB = 0x00;
  PORTB = 0xff;
  DDRC = 0x00;
  PORTC = 0xff;
  DDRD = 0x00;
  PORTD = 0xff;

  lcd_buf[0] = 0x0;
  lcd_buf[1] = 0x0;
  lcd_buf[2] = 0x0;
  lcd_buf[3] = 0x0;

  twi_begin();

  //   .    usbasp,     
  // ,  ,   
  // DDRB |= _BV(PB7);
  // PORTB |= _BV(PB7); // off

  //   -
  LCD_DDR |= (_BV(LCD_DATA1) | _BV(LCD_DATA2) | _BV(LCD_DATA3) | _BV(LCD_DATA4) | _BV(LCD_SCLK) | _BV(LCD_OE) | _BV(LCD_COM));
  cbi(LCD_PORT, LCD_SCLK);
  cbi(LCD_PORT, LCD_OE);

  // 
  KEY1_DDR &= ~(_BV(KEY1));
  KEY1_PORT |= _BV(KEY1);
  KEY2_DDR &= ~(_BV(KEY2));
  KEY2_PORT |= _BV(KEY2);

  //    ds1307   
  DS1307SQ_DDR &= ~_BV(DS1307SQ);
  DS1307SQ_PORT |= _BV(DS1307SQ);
  PCICR |= _BV(DS1307SQ_INT);
  DS1307SQ_MSK |= _BV(DS1307SQ);
  sei();

  // ds1307     ,     ,   
  //    ,    - 
  // setDS3231time(30,40,21,6,11,3,18);

  while(1)
  {
    byte need_render = 0;
    byte need_date_set = 0;

    //    ds1307,   
    // 
    if (need_render_int) {
      byte rc;
      if (mode == MODE_MAIN) {
        rc = readDS3231time_hms(&second, &minute, &hour);
      } else {
        rc = readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
      }
      if ( ! rc && twi_problems) {
        twi_problems -= 1;
      } else {
        twi_problems += rc;
      }
      need_render = 1;
      need_render_int = 0;
    }

    //    1/10 
    if ( ! cycle_count_10) {
      even_10 = ! even_10;

      //    ,   
      if (mode_timeout > 0) {
        mode_timeout -= 1;
      }
      //    ,    
      if (mode != MODE_MAIN && ! mode_timeout) {
        mode = MODE_MAIN;
        need_render = 1;
      }
      //      ,  10   
      if (mode == MODE_SET_MINUTE || mode == MODE_SET_HOUR || mode == MODE_SET_DAY || mode == MODE_SET_MONTH || mode == MODE_SET_YEAR) {
        need_render = 1; 
      }

      //  
      byte key1_down = (KEY1_PIN & _BV(KEY1)) ? 0 : 1;
      byte key2_down = (KEY2_PIN & _BV(KEY2)) ? 0 : 1;
      if (key1_down || key2_down || key1_press || key2_press) {
        need_render = 1;
      }
      if (key1_down && key1_press) {
        key1_time += 1;
      }
      if (key2_down && key2_press) {
        key2_time += 1;
      }
      //     
      if (key1_down && ! key1_press) {
          if (mode == MODE_SET_MINUTE) {
            mode = MODE_SET_HOUR;
            mode_timeout = MODE_TIMEOUT_SET;
          } else if (mode == MODE_SET_HOUR) {
            mode = MODE_SET_DAY;
            mode_timeout = MODE_TIMEOUT_SET;
          } else if (mode == MODE_SET_DAY) {
            mode = MODE_SET_MONTH;
            mode_timeout = MODE_TIMEOUT_SET;
          } else if (mode == MODE_SET_MONTH) {
            mode = MODE_SET_YEAR;
            mode_timeout = MODE_TIMEOUT_SET;
          } else if (mode == MODE_SET_YEAR) {
            mode = MODE_MAIN;
          } else if (mode == MODE_MAIN) {
            mode = MODE_SECOND;
            mode_timeout = MODE_TIMEOUT_SET;
          } else if (mode == MODE_SECOND) {
            mode = MODE_MAIN;
            mode_timeout = 0;
          }
      } else if ( ! key1_down && key1_press) {
        if (key1_time >= KEY_TIMEOUT) {
        } else {
        }
      } else if (key1_down && key1_press) {
        if (key1_time >= KEY_TIMEOUT) {
          if (mode == MODE_MAIN || mode == MODE_SECOND) {
            mode = MODE_SET_MINUTE;
            mode_timeout = MODE_TIMEOUT_SET;
          }
        } else {
        }
      }
      if (key2_down && ! key2_press) {
        if (mode == MODE_MAIN) {
          mode = MODE_CALENDAR;
          mode_timeout = MODE_TIMEOUT;
        } else if (mode == MODE_CALENDAR) {
          mode = MODE_YEAR;
          mode_timeout = MODE_TIMEOUT;
        } else if (mode == MODE_YEAR) {
          mode = MODE_MAIN;
          mode_timeout = 0;
        } else if (mode == MODE_SET_MINUTE) {
          minute += 1;
          mode_timeout = MODE_TIMEOUT_SET;
          need_date_set = 1;
        } else if (mode == MODE_SET_HOUR) {
          hour += 1;
          mode_timeout = MODE_TIMEOUT_SET;
          need_date_set = 1;
        } else if (mode == MODE_SET_DAY) {
          dayOfMonth += 1;
          mode_timeout = MODE_TIMEOUT_SET;
          need_date_set = 1;
        } else if (mode == MODE_SET_MONTH) {
          month += 1;
          mode_timeout = MODE_TIMEOUT_SET;
          need_date_set = 1;
        } else if (mode == MODE_SET_YEAR) {
          year += 1;
          mode_timeout = MODE_TIMEOUT_SET;
          need_date_set = 1;
        } else if (mode == MODE_SECOND) {
            second = 0;
            need_date_set = 1;
            mode_timeout = MODE_TIMEOUT_SET;
        }
      } else if ( ! key2_down && key2_press) {
        if (key2_time >= KEY_TIMEOUT) {
        } else {
        }
      } else if (key2_down && key2_press) {
        if (key2_time >= KEY_TIMEOUT) {
          if (mode == MODE_SET_MINUTE) {
            minute += 1;
            mode_timeout = MODE_TIMEOUT_SET;
            need_date_set = 1;
          } else if (mode == MODE_SET_HOUR) {
            hour += 1;
            mode_timeout = MODE_TIMEOUT_SET;
            need_date_set = 1;
          } else if (mode == MODE_SET_DAY) {
            dayOfMonth += 1;
            mode_timeout = MODE_TIMEOUT_SET;
            need_date_set = 1;
          } else if (mode == MODE_SET_MONTH) {
            month += 1;
            mode_timeout = MODE_TIMEOUT_SET;
            need_date_set = 1;
          } else if (mode == MODE_SET_YEAR) {
            year += 1;
            mode_timeout = MODE_TIMEOUT_SET;
            need_date_set = 1;
          }
        } else {
        }
      }
      key1_press = key1_down;
      if ( ! key1_press) {
        key1_time = 0;
      }
      key2_press = key2_down;
      if ( ! key2_press) {
        key2_time = 0;
      }
    }

    if (need_date_set) {
      //  
      //       ds1307    ,
      // ,  ,    
      if (minute > 59) {
        minute = 0;
      }
      if (hour > 23) {
        hour = 0;
      }
      if (dayOfMonth > 31) {
        dayOfMonth = 1;
      }
      if (month > 12) {
        month = 1;
      }
      if (year > 99) {
        year = 0;
      }
      //    ds1307
      setDS3231time(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
    }

    // ,    
    if (need_render) {
      do_render();
    }

    //  
    cli();
    lcd_refresh();
    sei();

    _delay_ms(10);

    cycle_count_10 += 1;
    if (cycle_count_10 >= 10) {
      cycle_count_10 = 0;
    }
  }

  return 0;
}

//    -   
byte decToBcd(byte val)
{
  return( (val/10*16) + (val%10) );
}
byte bcdToDec(byte val)
{
  return( (val/16*10) + (val%16) );
}

//    ds1307
void setDS3231time(byte second, 
                   byte minute, 
                   byte hour, 
                   byte dayOfWeek, 
                   byte dayOfMonth, 
                   byte month, 
                   byte year)
{
  twi_write((uint8_t) DS3231_I2C_ADDRESS, (uint8_t) 0, (uint8_t) decToBcd(second));
  twi_write((uint8_t) DS3231_I2C_ADDRESS, (uint8_t) 1, (uint8_t) decToBcd(minute));
  twi_write((uint8_t) DS3231_I2C_ADDRESS, (uint8_t) 2, (uint8_t) decToBcd(hour));
  twi_write((uint8_t) DS3231_I2C_ADDRESS, (uint8_t) 3, (uint8_t) decToBcd(dayOfWeek));
  twi_write((uint8_t) DS3231_I2C_ADDRESS, (uint8_t) 4, (uint8_t) decToBcd(dayOfMonth));
  twi_write((uint8_t) DS3231_I2C_ADDRESS, (uint8_t) 5, (uint8_t) decToBcd(month));
  twi_write((uint8_t) DS3231_I2C_ADDRESS, (uint8_t) 6, (uint8_t) decToBcd(year));
  //     SQ 1Hz
  //        ,   ds1307    
  //      8kHz
  twi_write((uint8_t) DS3231_I2C_ADDRESS, (uint8_t) 7, (uint8_t) 0b00010000);
}

//    ds1307
byte readDS3231time(byte *second,
                    byte *minute,
                    byte *hour,
                    byte *dayOfWeek,
                    byte *dayOfMonth,
                    byte *month,
                    byte *year)
{
  byte rc = twi_read(DS3231_I2C_ADDRESS, 0, 7);
  if (rc) return 1;
  *second = bcdToDec(twi_receive() & 0x7f);
  *minute = bcdToDec(twi_receive());
  *hour = bcdToDec(twi_receive() & 0x3f);
  *dayOfWeek = bcdToDec(twi_receive());
  *dayOfMonth = bcdToDec(twi_receive());
  *month = bcdToDec(twi_receive());
  *year = bcdToDec(twi_receive());
}

//   ,   ,  ,   
byte readDS3231time_hms(byte *second, byte *minute, byte *hour) {
  byte rc = twi_read(DS3231_I2C_ADDRESS, 0, 3);
  if (rc) return 1;
  *second = bcdToDec(twi_receive() & 0x7f);
  *minute = bcdToDec(twi_receive());
  *hour = bcdToDec(twi_receive() & 0x3f);
}

/*
 *  ,   ,  : http://dsscircuits.com/articles/arduino-i2c-master-library
 *      ,         4k  .
 */
/*
  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#define START           0x08
#define REPEATED_START  0x10
#define MT_SLA_ACK  0x18
#define MT_SLA_NACK 0x20
#define MT_DATA_ACK     0x28
#define MT_DATA_NACK    0x30
#define MR_SLA_ACK  0x40
#define MR_SLA_NACK 0x48
#define MR_DATA_ACK     0x50
#define MR_DATA_NACK    0x58
#define LOST_ARBTRTN    0x38
#define TWI_STATUS      (TWSR & 0xF8)
#define SLA_W(address)  (address << 1)
#define SLA_R(address)  ((address << 1) + 0x01)

#define MAX_BUFFER_SIZE 32

uint8_t twi_bytesAvailable = 0;
uint8_t twi_bufferIndex = 0;
uint8_t twi_totalBytes = 0;
uint16_t twi_timeOutDelay = 0;
uint8_t twi_returnStatus;
uint8_t twi_nack;
uint8_t twi_data[MAX_BUFFER_SIZE];

void twi_begin()
{
  sbi(PORTC, 4);
  sbi(PORTC, 5);
  cbi(TWSR, TWPS0);
  cbi(TWSR, TWPS1);
  TWBR = ((F_CPU / 100000) - 16) / 2;
  TWCR = _BV(TWEN) | _BV(TWEA); 
}
uint8_t twi_read(uint8_t address, uint8_t registerAddress, uint8_t numberBytes)
{
  twi_bytesAvailable = 0;
  twi_bufferIndex = 0;
  if(numberBytes == 0){numberBytes++;}
  twi_nack = numberBytes - 1;
  twi_returnStatus = 0;
  twi_returnStatus = twi_start();
  if(twi_returnStatus){return(twi_returnStatus);}
  twi_returnStatus = twi_sendAddress(SLA_W(address));
  if(twi_returnStatus)
  {
    if(twi_returnStatus == 1){return(2);}
    return(twi_returnStatus);
  }
  twi_returnStatus = twi_sendByte(registerAddress);
  if(twi_returnStatus)
  {
    if(twi_returnStatus == 1){return(3);}
    return(twi_returnStatus);
  }
  twi_returnStatus = twi_start();
  if(twi_returnStatus)
  {
    if(twi_returnStatus == 1){return(4);}
    return(twi_returnStatus);
  }
  twi_returnStatus = twi_sendAddress(SLA_R(address));
  if(twi_returnStatus)
  {
    if(twi_returnStatus == 1){return(5);}
    return(twi_returnStatus);
  }
  for(uint8_t i = 0; i < numberBytes; i++)
  {
    if( i == twi_nack )
    {
      twi_returnStatus = twi_receiveByte(0);
      if(twi_returnStatus == 1){return(6);}
      if(twi_returnStatus != MR_DATA_NACK){return(twi_returnStatus);}
    }
    else
    {
      twi_returnStatus = twi_receiveByte(1);
      if(twi_returnStatus == 1){return(6);}
      if(twi_returnStatus != MR_DATA_ACK){return(twi_returnStatus);}
    }
    twi_data[i] = TWDR;
    twi_bytesAvailable = i+1;
    twi_totalBytes = i+1;
  }
  twi_returnStatus = twi_stop();
  if(twi_returnStatus)
  {
    if(twi_returnStatus == 1){return(7);}
    return(twi_returnStatus);
  }
  return(twi_returnStatus);
}
uint8_t twi_write(uint8_t address, uint8_t registerAddress, uint8_t data)
{
  twi_returnStatus = 0;
  twi_returnStatus = twi_start(); 
  if(twi_returnStatus){return(twi_returnStatus);}
  twi_returnStatus = twi_sendAddress(SLA_W(address));
  if(twi_returnStatus)
  {
    if(twi_returnStatus == 1){return(2);}
    return(twi_returnStatus);
  }
  twi_returnStatus = twi_sendByte(registerAddress);
  if(twi_returnStatus)
  {
    if(twi_returnStatus == 1){return(3);}
    return(twi_returnStatus);
  }
  twi_returnStatus = twi_sendByte(data);
  if(twi_returnStatus)
  {
    if(twi_returnStatus == 1){return(3);}
    return(twi_returnStatus);
  }
  twi_returnStatus = twi_stop();
  if(twi_returnStatus)
  {
    if(twi_returnStatus == 1){return(7);}
    return(twi_returnStatus);
  }
  return(twi_returnStatus);
}
uint8_t twi_receive()
{
  twi_bufferIndex = twi_totalBytes - twi_bytesAvailable;
  if(!twi_bytesAvailable)
  {
    twi_bufferIndex = 0;
    return(0);
  }
  twi_bytesAvailable--;
  return(twi_data[twi_bufferIndex]);
}
uint8_t twi_start()
{
  unsigned long startingTime = millis();
  TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
  while (!(TWCR & (1<<TWINT)))
  {
    if(!twi_timeOutDelay){continue;}
    if((millis() - startingTime) >= twi_timeOutDelay)
    {
      twi_lockUp();
      return(1);
    }

  }
  if ((TWI_STATUS == START) || (TWI_STATUS == REPEATED_START))
  {
    return(0);
  }
  if (TWI_STATUS == LOST_ARBTRTN)
  {
    uint8_t bufferedStatus = TWI_STATUS;
    twi_lockUp();
    return(bufferedStatus);
  }
  return(TWI_STATUS);
}
uint8_t twi_sendAddress(uint8_t i2cAddress)
{
  TWDR = i2cAddress;
  unsigned long startingTime = millis();
  TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)))
  {
    if(!twi_timeOutDelay){continue;}
    if((millis() - startingTime) >= twi_timeOutDelay)
    {
      twi_lockUp();
      return(1);
    }

  }
  if ((TWI_STATUS == MT_SLA_ACK) || (TWI_STATUS == MR_SLA_ACK))
  {
    return(0);
  }
  uint8_t bufferedStatus = TWI_STATUS;
  if ((TWI_STATUS == MT_SLA_NACK) || (TWI_STATUS == MR_SLA_NACK))
  {
    twi_stop();
    return(bufferedStatus);
  }
  else
  {
    twi_lockUp();
    return(bufferedStatus);
  } 
}
uint8_t twi_sendByte(uint8_t i2cData)
{
  TWDR = i2cData;
  unsigned long startingTime = millis();
  TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)))
  {
    if(!twi_timeOutDelay){continue;}
    if((millis() - startingTime) >= twi_timeOutDelay)
    {
      twi_lockUp();
      return(1);
    }

  }
  if (TWI_STATUS == MT_DATA_ACK)
  {
    return(0);
  }
  uint8_t bufferedStatus = TWI_STATUS;
  if (TWI_STATUS == MT_DATA_NACK)
  {
    twi_stop();
    return(bufferedStatus);
  }
  else
  {
    twi_lockUp();
    return(bufferedStatus);
  } 
}
uint8_t twi_receiveByte(uint8_t ack)
{
  unsigned long startingTime = millis();
  if(ack)
  {
    TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);

  }
  else
  {
    TWCR = (1<<TWINT) | (1<<TWEN);
  }
  while (!(TWCR & (1<<TWINT)))
  {
    if(!twi_timeOutDelay){continue;}
    if((millis() - startingTime) >= twi_timeOutDelay)
    {
      twi_lockUp();
      return(1);
    }
  }
  if (TWI_STATUS == LOST_ARBTRTN)
  {
    uint8_t bufferedStatus = TWI_STATUS;
    twi_lockUp();
    return(bufferedStatus);
  }
  return(TWI_STATUS); 
}
uint8_t twi_stop()
{
  unsigned long startingTime = millis();
  TWCR = (1<<TWINT)|(1<<TWEN)| (1<<TWSTO);
  while ((TWCR & (1<<TWSTO)))
  {
    if(!twi_timeOutDelay){continue;}
    if((millis() - startingTime) >= twi_timeOutDelay)
    {
      twi_lockUp();
      return(1);
    }

  }
  return(0);
}
void twi_lockUp()
{
  TWCR = 0;
  TWCR = _BV(TWEN) | _BV(TWEA);
}

. , , тАФ . , 1MHz, , 6mA. . , , : USBasp- .


, AVR- " ". ! , 100 . 65ms, , .


, - , , , 7805 , - .


! . , - , , , ? , . STM8/32? MSP430? , -, AVR?




UPD


, , . . , i2c ds1307. , VCC 1.2*VBAT. , i2c. : , +5v - 2.5v, i2c , . VBAT Tiny RTC 3v. .


. , . тАФ , , 595, . , RCLK, , , , . , , . , .


, . - , , , , AVR 65 . , , . , AVR , , , . olartamonov .


, , 6mA , lm7805, (Vout ; Vin ). тАФ 4mA.


, 0.3 1.6 mA. , тАФ , , .


тАФ ! , , 595- 555 , - , 32 595-. - :-)

Source: https://habr.com/ru/post/hi410899/


All Articles